DRF認證組件流程分析

視圖函數中加上認證功能,流程見下圖

import hashlib
import time
def get_random(name):
    md = hashlib.md5()
    md.update(bytes(str(time.time()),encoding='utf-8'))
    md.update(bytes(name,encoding='utf-8'))
    return md.hexdigest()
from rest_framework.views import APIView
class Login(APIView):
    authentication_classes = [AuthLogin]
    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': None}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        user = models.User.objects.filter(name=name, password=pwd).first()
        if user:
            response['msg'] = '登錄成功'
            # 隨機字符串能夠是用戶名加當前時間生成的mds
            token = get_random(name)
            # 若是有記錄,就只須要更新,不須要從新插入
            # models.UserToken.objects.create(token=token,user=user)
            # 查詢 更新
            # user_agent
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        else:
            response['status'] = 101
            response['msg'] = '用戶名或密碼錯誤'
        return Response(response)
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import NotAuthenticated
from app01 import models
# BaseAuthentication
class AuthLogin(BaseAuthentication):
    def authenticate(self, request):
        # 封裝後的request
        token = request.GET.get('token')
        # print(token)
        ret = models.UserToken.objects.filter(token=token).first()
        if ret:
            return ret.user,token
        else:
            raise NotAuthenticated('您沒有登錄')

在def initial(self, request, *args, **kwargs):函數中找到認證功能
app

流程總結:

  • dispatch 方法裏self.initial裏面有個認證組件self.perform_authentication(request)
  • 到了APIview 返回了request.user (封裝後的Request)
  • 去request類裏找user方法,被包裝成了屬性,裏面執行了一個方法,self._authticate方法
  • self._authticate方法裏從本身的authenticators一個一個的取東西,authenticators
  • 因而查看authenticators,是初始化的時候init傳過來了,self.authenticators = authenticators or()
  • 到dispatch裏找初始化的時候,也就是APIView的initialize_request方法傳了self.authenticators,裏面是一個get_authenticators的方法
  • self.authentication_classes 是[類1,類2,類3]一個一個取,加括號執行。生成一個一個對象.最後返回到前面的Request的_authenticate方法
  • 拿到對象以後,執行user_auth_tuple = authenticator.authenticate(self)
  • 注意authenticate是須要在視圖函數中本身定義的,self.user, self.auth = user_auth_tuple返回兩個值,流程結束。
相關文章
相關標籤/搜索