0
点赞
收藏
分享

微信扫一扫

drf 认证组件

Java旺 2022-03-12 阅读 50

文章目录

drf 认证组件

认证的写法

认证的源码分析

查看源码步骤:

  1. APIVIew---->dispatch方法—>self.initial(request, *args, **kwargs)---->有认证,权限,频率

  2. 只读认证源码: self.perform_authentication(request)

  3. self.perform_authentication(request)就一句话:request.user,需要去drf的Request对象中找user属性(方法)

  4. Request类中的user方法,刚开始来,没有_user,走 self._authenticate()

  5. 核心就是Request类的 _authenticate(self):

def _authenticate(self):
        # 遍历拿到一个个认证器,进行认证
        # self.authenticators配置的一堆认证类产生的认证类对象组成的 list
        # self.authenticators 你在视图类中配置的一个个的认证类:authentication_classes=[认证类1,认证类2],对象的列表
        for authenticator in self.authenticators:
            try:
                # 认证器(对象)调用认证方法authenticate(认证类对象self, request请求对象)
                # 返回值:登陆的用户与认证的信息组成的 tuple
                # 该方法被try包裹,代表该方法会抛异常,抛异常就代表认证失败
                user_auth_tuple = authenticator.authenticate(self) #注意这self是request对象
            except exceptions.APIException:
                self._not_authenticated()
                raise

            # 返回值的处理
            if user_auth_tuple is not None:
                self._authenticator = authenticator
                # 如何有返回值,就将 登陆用户 与 登陆认证 分别保存到 request.user、request.auth
                self.user, self.auth = user_auth_tuple
                return
        # 如果返回值user_auth_tuple为空,代表认证通过,但是没有 登陆用户 与 登陆认证信息,代表游客
        self._not_authenticated()

认证组件的使用

# app01_auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01 import models

class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 认证逻辑,如果认证通过,返回两个值
        # 如果认证失败,抛出AuthenticationFailed异常
        token = request.GET.get('token')
        if token:
            user_token = models.UserToken.objects.filter(token=token).first()
            # 认证通过
            if user_token:
                return user_token.user, token
            raise AuthenticationFailed('认证失败')
        raise AuthenticationFailed('请求地址中需要携带token')

全局使用

# 在setting.py中配置
REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}

局部使用

# 在视图类上写
authentication_classes=[MyAuthentication]
# 局部禁用
authentication_classes=[]
举报

相关推荐

0 条评论