Vue+Django做API鉴权

/ vueapi安全 / 没有评论 / 1852浏览

功能

实现针对不同的API去判断是否具有权限,去拦截或放行,当前这些逻辑需要和前端紧密配合

Vue 前端

全局拦截与响应处理

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  let token = localStorage.getItem('ChaosToken')
  if (token) {
    config.headers.Authorization = token
  }
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, function (error) {
  // 对响应错误做点什么
  if (error) {
    // 请求配置发生的错误
    if (!error.response) {
      return console.log('Error', error.message);
    }

    // 获取状态码
    const status = error.response.status;

    // 错误状态处理
    if (status === 403) {
      ElementUI.Message({
        message: '您没有权限哦 🐒',
        duration:'2000',
        type: 'warning'
      });
      // router.push('/view')
    } else if (status === 500){
      ElementUI.Message({
        message: '服务器端错误 🐒',
        duration:'1000',
        type: 'error'
      });
    }else if (status === 400){
      ElementUI.Message({
        message: '需要认证 🐒',
        duration:'1000',
        type: 'warning'
      });
      window.localStorage.clear();
      window.location.href = 'https://xxx.com/sso/login/'+process.env.AEGIS_KEY;
    }else if (status >= 404 && status < 422) {
      ElementUI.Message({
        message: '未知错误 🐒',
        duration:'2000',
        type: 'error'
      });
    }

  }
  return Promise.reject(error);
});

Django 后端

登录逻辑 Code

class LoginReturn(APIView):
    def get(self, request):
        response = {
            'code': 4001,
            'username': '',
            'token': '',
            'msg': '认证成功',
        }
        HTTPToken = request.META.get("HTTP_AUTHORIZATION")
        print(SearchTokenName(HTTPToken))
        if SearchTokenName(HTTPToken) == 404:
            token = request.GET.get('token')
            if token is None:
                response['msg'] = "Token为空"
                return Response(response, status=400)
            if SearchTokenName(token) == 404:
                response['msg'] = "需要认证"
                return Response(response, status=400)
        username = SearchTokenName(token)[0]
        username_per = SearchTokenName(token)[1]
        cache.set(token, {"username": username, "per": username_per}, timeout=60 * 60 * 24)
        PrintLog = "token -> %s |username -> %s|per -> %s |" % (token, username, username_per)
        print(PrintLog)
        response['username'] = username
        response['token'] = token
        response['msg'] = "认证成功"
        response['code'] = 200
        return Response(response, status=200)  # 返回成功数据

登录之后认证逻辑Code

from chaos_api.util.SearchTokenUserPer import SearchTokenName
from django.core.cache import cache
from django.utils.deprecation import MiddlewareMixin
from django.http import JsonResponse


def process_request(request):
    print("Auth鉴权请求 -> Success !")


class AuthMidddleware(MiddlewareMixin):

    def process_response(self, request, response):
     		# 截取请求的url , xxx.com/api/url
        AccessURL = (request.path).split("/")[2]
        #  获取登录之后存在本地浏览器的Token
        HTTPToken = request.META.get("HTTP_AUTHORIZATION")
        # 受保护的Url列表
        SafeUrlList = ["AddProject", "SelectAllOfflineProject", "SelectAllOnlineProject", "SendMsg"]
        if AccessURL in SafeUrlList:
            # 加上此项判断会存在用户删除之后,凭浏览器存在的token缓存还能访问敏感url
            if cache.has_key(HTTPToken) == 0:
                DebugMsg = "|访问敏感url |AccessURL -> %s | HTTP Token -> %s | Redis中Token是否存在 -> %s " % (
                    AccessURL, HTTPToken, cache.has_key(HTTPToken))
                print(DebugMsg)
                print("Auth鉴权返回 -> Error !")
                return JsonResponse({'msg': "认证失败", 'status': 400}, status=400)
            # 实时判断权限
            if SearchTokenName(HTTPToken) == 404:
                DebugMsg = "|访问敏感url|AccessURL -> %s | HTTP Token -> %s | UserName -> %s | Per -> %s" % (
                    AccessURL, HTTPToken, cache.get(HTTPToken).get('username'), cache.get(HTTPToken).get('per'))
                print(DebugMsg)
                print("Auth鉴权返回 -> Error !")
                return JsonResponse({'msg': "认证失败", 'status': 400}, status=400)
            if SearchTokenName(HTTPToken)[1] != 'sre':
              	print("Auth鉴权返回 -> Error !")
                return JsonResponse({'msg': "认证失败", 'status': 400}, status=400)
            else:
                return response
        return response
      	print("Auth鉴权返回 -> Success !")

加载到Django项目中

setting.py

MIDDLEWARE = [
		···
    'chaos_api.common.auth_middleware.AuthMidddleware'
    ···
]