使用的是Vue Element Admin template 基础模板
1 修改 src/api/user.js
import request from \'@/utils/request\'
export function login(data) {
return request({
url: \'/auth/\',
method: \'post\',
data
})
}
export function getInfo(token) {
return request({
url: \'/userInfo/\',
method: \'post\',
data:{\'token\':token}
})
}
export function logout() {
return request({
url: \'/logout/\',
method: \'post\'
})
}
2 修改src/store/modules/user.js
import { login, logout, getInfo } from \'@/api/user\'
import { getToken, setToken, removeToken } from \'@/utils/auth\'
import { resetRouter } from \'@/router\'
const getDefaultState = () => {
return {
token: getToken(),
name: \'\',
avatar: \'\'
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
}
}
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response.data
commit(\'SET_TOKEN\', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response.data
if (!data) {
return reject(\'Verification failed, please Login again.\')
}
const { name, avatar } = data
commit(\'SET_NAME\', name)
commit(\'SET_AVATAR\', avatar)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
removeToken() // must remove token first
resetRouter()
commit(\'RESET_STATE\')
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
removeToken() // must remove token first
commit(\'RESET_STATE\')
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
3,修改src/utils/request.js
import axios from \'axios\'
import { MessageBox, Message } from \'element-ui\'
import store from \'@/store\'
import { getToken } from \'@/utils/auth\'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_URL, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token
// [\'X-Token\'] is a custom headers key
// please modify it according to the actual situation
//把Token信息加到请求头部
config.headers[\'X-Token\'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
export default service
4 配置后端接口
from django.http import JsonResponse
from rest_framework.views import APIView
from api import models
from api.logger import logger
def create_token(user):
import hashlib
import time
#获取当前时间戳用作随机字符串
ctime = str(time.time())
m = hashlib.md5(bytes(user,encoding=\'utf-8\'))
m.update(bytes(ctime,encoding=\'utf-8\'))
return m.hexdigest()
class AuthView(APIView):
"""
用户登陆认证,生成并保存token
"""
authentication_classes = []
def post(self,request,*args,**kwargs):
ret = {"code": 200, "status": "success", "data": {"token": None}}
username = request.data.get(\'username\')
password = request.data.get(\'password\')
try:
obj = models.Users.objects.filter(username=username,password=password).first()
if obj:
#为用户创建token,如果已存在则更新,否则创建
token = create_token(username)
models.UserToken.objects.update_or_create(user=obj,defaults={\'token\':token})
ret[\'status\'] = \'success\'
ret[\'data\'][\'token\'] = token
else:
ret[\'code\'] = 401
ret[\'status\'] = \'用户名或密码错误\'
except Exception as e:
logger.error(e)
ret[\'code\'] = 400
ret[\'status\'] = \'error\'
return JsonResponse(ret)
class AuthInfoView(APIView):
"""
获取登陆用户信息
"""
def post(self,request,*args,**kwargs):
ret = {"code":200,"status":"success","data":{"roles":[],"introduction": \'\',
"avatar": \'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif\',
"name": \'\'}}
token = request.data.get(\'token\')
try:
obj = models.UserToken.objects.filter(token=token).first()
if obj:
ret[\'status\'] = \'success\'
ret[\'data\'][\'name\'] = obj.user.username
for i in obj.user.roles.all():
ret[\'data\'][\'roles\'].append(i.title)
else:
ret[\'code\'] = 401
ret[\'status\'] = \'认证失败\'
except Exception as e:
logger.error(e)
ret[\'code\'] = 400
ret[\'status\'] = \'error\'
return JsonResponse(ret)
class LogoutView(APIView):
"""
退出登陆
"""
def post(self,request,*args,**kwargs):
ret = {"code":200,"status":"success","data":\'success\'}
token = request.META.get(\'HTTP_X_TOKEN\')
try:
obj = models.UserToken.objects.filter(token=token).first()
if obj:
obj.delete()
else:
ret[\'code\'] = 401
ret[\'status\'] = \'退出失败\'
except Exception as e:
logger.error(e)
ret[\'code\'] = 400
ret[\'status\'] = \'error\'
return JsonResponse(ret)
5 后端token认证
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from api import models
class Authentication(BaseAuthentication):
def authenticate(self, request):
#获取请求头部的token
token = request.META.get(\'HTTP_X_TOKEN\')
token_obj = models.UserToken.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed(\'用户认证失败\')
return (token_obj.user,token_obj)
ps:携带token认证时出现了跨域问题(中间件配置)
from django.utils.deprecation import MiddlewareMixin
class CORSMiddleware(MiddlewareMixin):
def process_response(self, request, response):
# 添加响应头
# 允许你的域名来获取我的数据
# 允许所有的域名来获取数据
response[\'Access-Control-Allow-Origin\'] = \'*\'
# 允许你携带Content-Type请求头 如果要多的用逗号,隔开
response[\'Access-Control-Allow-Headers\'] = \'*\'
return response
配置setting
MIDDLEWARE = [
\'api.cors.CORSMiddleware\', #跨域请求CORS
]