• Vue Element Admin 登陆认证


    使用的是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
    ]
    

      

  • 相关阅读:
    列表、元组、字符串的相互转化
    python中的常用BIF
    python中的类型
    python内置模块
    打印字体颜色整理
    xml操作
    内置函数
    迭代器
    装饰器
    函数
  • 原文地址:https://www.cnblogs.com/xiao2er/p/13331616.html
Copyright © 2020-2023  润新知