DRF之认证组件

一:源码分析

(1)认证组件

(1)视图

PIView的dispath(self, request, *args, **kwargs)   
知识兔

(2)任务分发

ispath方法内 self.initial(request, *args, **kwargs) 进入三大认证
知识兔

(3)认证组件

  self.perform_authentication(request)
知识兔

(4)认证功能介绍

  (1)其主要用来对用户进行认证

  (2)检验用户 ----> 普通游客 | 合法用户 | 非法用户

  (3)游客:代表认证通过 直接进入下一步(权限校验)

  (2)合法用户:携带验证信息进行验证 验证通过将用户存储进入request.user中 再次进行下一步校验

  (3)非法用户:携带验证信息进行验证 验证失败直接抛出异常 返回403权限问题

(2)源码分析

(1)第一步APIView/dispatch/initial

def initial(self, request, *args, **kwargs):# Ensure that the incoming request is permitted
        self.perform_authentication(request) # 认证功能
        self.check_permissions(request)      # 访问权限功能
        self.check_throttles(request)       # 频率功能
知识兔

(2)第二步进入认证功能

def perform_authentication(self, request):

        request.user   # 得到一个方法属性 get方法
     PS: 如果是复制属性 应该是request.user = XXX
知识兔

(3)第三步进入request/user

    @property
    def user(self):
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()     # 没有用户认证处用户
        return self._user  # 如果有直接返回用户
知识兔

(4)第四步_authenticate

def _authenticate(self):
        # self.authenticators:一堆认证类产生序列化认证对象的集合体(列表)
        for authenticator in self.authenticators:   # 循环遍历集合体拿到一个个认证对象
            try:
                '''
                authenticator.authenticate:认证对象调用认证功能
                user_auth_tuple:拿到登录的用户与用户信息的返回值
                
                调用改方法传入两个参数 self,request
                self:当前认证类对象
                request:当前请求用户
                
                '''
                user_auth_tuple = authenticator.authenticate(self)
            except exceptions.APIException:
                # 抛出异常代表认证失败
                self._not_authenticated()
                raise

            if user_auth_tuple is not None:
                self._authenticator = authenticator
                # 如果有返回值 将登录用户 与 验证信息 保存在 request.user ,request.author
                self.user, self.auth = user_auth_tuple

                return
        # 如果返回值为空 代表认证通过 但是没有登录用户 与验证信息 表示当前用户为游客用户
        self._not_authenticated()
知识兔

(5)自定义认证组件

(1)全局settings文件配置

 {
    # 全局配置异常模块
    'EXCEPTION_HANDLER': 'utils.exception.exception_handler',
    # 认证类配置
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 'rest_framework.authentication.SessionAuthentication',
        # 'rest_framework.authentication.BasicAuthentication',
        'api.authentications.MyAuthentication',  # 自定义认证组件
    ],
    # 权限类配置
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
}
知识兔

(2)自定义文件配置api/Authentication

from rest_framework.exceptions import AuthenticationFailed
from rest_framework.authentication import BaseAuthentication
from . import models
class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        '''
        前台在请求头携带认证信息,
        且默认规范用 Authorization 字段携带认证信息,
        后台固定在请求对象的META字段中 HTTP_AUTHORIZATION 获取

        '''
        auth = request.META.get('HTTP_AUTHORIZATION',None)   # 可以不携带认证信息

        if auth is None:  # 如果为空则表明游客
            return None  # 没有登录用户 与 返回信息

        auth_list = auth.split()  # 设置认证小规则(两段式)

        # 判断用户是否合法
        if not (len(auth_list) == 2 and auth_list[0].lower() == 'auth'):
            raise AuthenticationFailed('认证信息有误 非法用户')  # 非法的请求 直接抛出异常

        # 解析合法的用户
        if not auth_list[1] == 'qwe.asd.zxc':   # 假设通过解析'qwe.asd.zxc' 可以解析处合法用户
            raise AuthenticationFailed('用户校验失败 非法用户')

        user_obj = models.User.objects.filter(username='admin').first()
        if not user_obj:
            raise AuthenticationFailed('用户数据有误 非法用户')
        return (user_obj,None)   # 合法将用户返回 验证信息不返回
知识兔

(3)视图层

from rest_framework.views import APIView
from rest_framework.response import Response

class TestAPIView(APIView):
    def get(self,request,*args,**kwargs):
        '''
        测试一:前段不输入校验信息 获取用户属于匿名用户
        测试二:前段加入验证信息  获取用户属于解析用户 admin
        '''
        print(request.user)
        return Response(
            {
                'status':0,
                'msg':'测试成功'
            }
        )
知识兔

  

计算机