yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

  • django-DRF

    • win环境快速搭建drf项目
    • DRF介绍及快速使用
    • 序列化
    • DRF请求和响应
    • DRF类视图
    • 认证
      • 链接资料
      • 1. 认证
        • 1.1 初始认证
        • 1、DRF中的认证方法
        • 2、示例
        • 想要功能
      • 2. DRF认证方式
        • 2.1 BasicAuthentication(用户名密码认证)
        • 全局认证
        • 局部认证
        • 2.2 TokenAuthentication认证
        • 基础配置
        • a. 安装rest_framework.authtoken
        • b. 全局配置和局部配置
        • c. 全局配置单个不配置
        • 路由配置
        • 传递方式
        • 2.3 SessionAuthentication验证
        • django中有自带的登录和退出
        • 详细查看
        • 2.4 自定义认证
        • a. 初始化操作
        • b. 自定义认证编写(认证源码分析)
        • c. 自定义认证类
        • d. 在视图中使用
        • 2.5 JWT 认证示例
        • 2.6 匿名用户(未登录用户)
      • 3. 认证流程原理
        • 自定义认证类示例
      • 4. 梳理
    • 权限
    • 接口访问控制(限流)
    • 版本
    • 分页
    • 解析器
    • 自定义异常格式
    • 自定义响应格式
    • 过滤
    • 搜索
    • 排序
  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • django-DRF
YiZhang-You
2023-05-20
目录

认证

# 链接资料

  1. 博客园极其内向的帅小伙

    1-2 前后端分离介绍-前后端分离介绍 (opens new window)

  2. drf官方文档

    Home - Django REST framework (opens new window)

  3. drf官方源码地址

    GitHub - encode/django-rest-framework: Web APIs for Django. 🎸 (opens new window)

  4. 功能大致脑图

    (opens new window)

# 1. 认证

# 1.1 初始认证

有些API需要用户登录成功之后,才能访问;有些无需登录就能访问。
	把token值存放起来

请求来了,执行了View类中as_view的view()方法,本质上执行了self.dispatch方法
按顺序查找dispatch方法(自己类中,父类中,父父类中...)
在APIView中的dispatch方法中先把原来request封装进去,变成新的request对象
接下来又执行了三个组件,分别是认证,权限和频率
如果三个中有一个不满足,则不继续执行
再走分发方法,最后返回response出去
即在请求进入视图函数前加了一些东西,重写了dispatch方法
1
2
3
4
5
6
7
8
9
10
现在我们写的接口,会发现一个问题,就是任何人都可以创建数据库,修改数据。这样肯定是不行的,我们希望只有数据的创建者才能有权限修改数据,如果不是,只能有只读权限。这个好比什么呐?好比我们有一个购物车的话,去访问,我们就要去登录的情况下去访问。
1

其实在Django rest famework 已经默认帮我做认证了。我们可以去 看下源码:我们按 Ctrl + 类名:

views.APIView => APIView(View)
1

来我们看下 APIView 的源码:

class APIView(View):
    ....
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES   #权限认证
    ....
1
2
3
4

我们进入 Ctrl + api_settings 继续进去看:

api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)  
# 原来在这边,意思就是说 有配置权限的话就去读自己配置的,没有的话就读DEFAULTS
1
2

那我们进去看看 Ctrl + DEFAULTS 继续看看,默认的权限是啥?

EFAULTS = {
    # Base API policies
    .....,
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication', #session验证
        'rest_framework.authentication.BasicAuthentication' #客户端 用户名密码验证
    ),
    ....
}
1
2
3
4
5
6
7
8
9

DRF的的默认验证是 SessionAuthentication 和 BasicAuthentication。

认证失败会有两种可能的返回值

  • 401 Unauthorized 未认证
  • 403 Permission Denied 权限被禁止

# 1、DRF中的认证方法

  • BasicAuthentication:此身份验证方案使用**HTTP基本身份验证 (opens new window)*,根据用户的用户名和密码进行签名。基本身份验证通常仅适用于测试。
  • TokenAuthentication: 此身份验证方案使用基于令牌的简单HTTP身份验证方案。令牌认证适用于客户端 - 服务器设置,例如本机桌面和移动客户端。
  • SessionAuthentication: 此身份验证方案使用Django的默认会话后端进行身份验证。会话身份验证适用于与您的网站在同一会话上下文中运行的AJAX客户端。
  • RemoteUserAuthentication(不经常用,忘记):此身份验证方案允许您将身份验证委派给Web服务器,该服务器设置REMOTE_USER 环境变量。

说明:

  • BasicAuthentication:客户端用户名密码认证
  • TokenAuthentication:采用token值进行校验
  • SessionAuthentication:采用sessionid的方式进行校验。

# 2、示例

models.py

from django.db import models

class User(models.Model):
    """用户"""
    username = models.CharField(max_length=128, verbose_name="用户账号")
    password = models.CharField(max_length=128, verbose_name="用户密码")

class Game(models.Model):
    """游戏"""
    name = models.CharField(verbose_name="游戏名", max_length=64)
    desc = models.CharField(verbose_name="描述", max_length=20)
    user = models.ForeignKey(User, on_delete=models.CASCADE)  # 继承django自带的用户

    def __str__(self):
        return self.name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^user/$', views.UserView.as_view()),  # 查看所有用户
    url(r'^user/(?P<pk>\d+)/$', views.UserView.as_view()),  # 查看所有用户

    url(r'^game/$', views.GameList.as_view()),  # 游戏
    url(r'^game/<int:pk>/$', views.GameList.as_view()),
]
1
2
3
4
5
6
7
8
9
10
11

views.py

# 游戏
class GameSerializer(serializers.ModelSerializer):
    class Meta:
        model = Game
        fields = "__all__"

class GameList(APIView):  # ListCreateAPIView=>GenericAPIView => views.APIView => APIView(View)
	
    def get(self, request, *args, **kwargs):
        # http://127.0.0.1:8000/api/app01/game/ get
        data = Game.objects.filter()
        serializer = GameSerializer(data=data, many=True)
        serializer.is_valid()
        return Response({"code": 0, "message": "success", "data": serializer.data})

    def post(self, request, *args, **kwargs):
        # http://127.0.0.1:8000/api/app01/game/ post
        data = request.data
        serializer = GameSerializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"code": 0, "message": "success", "data": serializer.data})

class GameDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Game.objects.all()
    serializer_class = GameSerializer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 想要功能

我们需要用户自己添加自己喜欢的游戏,我们就需要登录

# 2. DRF认证方式

# 2.1 BasicAuthentication(用户名密码认证)

DRF的 APIView视图其实是自带了验证

# 全局认证

在settings.py中配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',  # session认证
        'rest_framework.authentication.BasicAuthentication',   # 基本认证
    )
}
1
2
3
4
5
6

全局配置单个不配置

authentication_classes = [] 
# 如果全局配置了,但是这个视图不需要验证,就authentication_classes 变成空列表
1
2

# 局部认证

在视图中单独声明

from rest_framework.views import APIView
from django.http import JsonResponse
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
 
class CartView(APIView):
    # 基于什么登录认证的(通过什么方式登录)
    authentication_classes = [BasicAuthentication] #对APIView的authentication_classes重写
    # 只有登录才能访问(权限控制你是否登录)
    permission_classes = [IsAuthenticated]  #查看IsAuthenticated源码 => Ctrl + IsAuthenticated
    def get(self, request, *args, **kwargs):
        data = {"code": 1,}
        return JsonResponse(data)
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.2 TokenAuthentication认证

# 基础配置

# a. 安装rest_framework.authtoken

说明:在settings.py的文件中INSTALLED_APPS配置

# settings.py
INSTALLED_APPS = (
    ...
    'rest_framework.authtoken'
)
 
#迁入数据
>python manage.py migrate
1
2
3
4
5
6
7
8

# b. 全局配置和局部配置

说明:

  • 如果是全局配置的话,需要在 settings.py文件中配置
  • 但是如果是局部配置,就要在具体的视图中配置。这个根据自己的需求来配置。
# settings.py配置  全局配置:表示对所有视图有效
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication', 
        'rest_framework.authentication.TokenAuthentication',
    ),
}
 
# 局部配置 :只对当前视图有效
from rest_framework.authentication import SessionAuthentication
from rest_framework.authentication import BasicAuthentication
from rest_framework.authentication import TokenAuthentication
 
class XXXX(APIView):
            authentication_classes = [BasicAuthentication,TokenAuthentication,SessionAuthentication]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# c. 全局配置单个不配置

说明:我们可能遇到这种情况,就是全局需要配置,但是我只是单单某个接口不需要认证。

class CartView(APIView):
    #局部的
 
    # 基于什么登录认证的
    authentication_classes = [] # 如果全局配置了,但是这个视图不需要验证,就authentication_classes 变成空列表
 
    # 只有登录才能访问
    permission_classes = [IsAuthenticated]
 
    def get(self, request, *args, **kwargs):
 
        .....
1
2
3
4
5
6
7
8
9
10
11
12

# 路由配置

我们配置token验证的时候,还有配置路由,验证登录之后,产生token值,后面其他接口 拿到 这个token 值放在 请求 header中,去校验。

在根级路由或者子路由中配置,这个你自己看,我们这边是根级路由配置

from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken import views  #设置路由,必须导入view
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-token-auth/', views.obtain_auth_token) #token哪里来,我们这边还需要配置一个路由,请求生成token
]
1
2
3
4
5
6
7
8

我们来看一下 obtain_auth_token 源码:Ctrl + obtain_auth_token 看一下:

obtain_auth_token =>  ObtainAuthToken
1

obtain_auth_token这个类自动帮我们生成一个token。

# 传递方式

封装到请求头中,已下面的格式
Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a
1
2

# 2.3 SessionAuthentication验证

使用方式配置方式和上面一样

from rest_framework.authentication import BasicAuthentication, TokenAuthentication, SessionAuthentication  #导入SessionAuthentication验证
from rest_framework.permissions import IsAuthenticated
 
# Create your views here.
 
class CartView(APIView):
    # 基于什么登录认证的
    authentication_classes = [BasicAuthentication, TokenAuthentication, SessionAuthentication]  #支持session验证,三者任何一种验证都可以,这边我们主要用 Session验证
    # 只有登录才能访问
    permission_classes = [IsAuthenticated]
    def get(self, request, *args, **kwargs):
 
        ....
 
        return JsonResponse(ctx)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# django中有自带的登录和退出

from django.contrib.auth import login
from django.contrib.auth import logout
1
2

# 详细查看

6-5 认证和权限-DRF认证之SessionAuthentication认证 (opens new window)

# 2.4 自定义认证

# a. 初始化操作

模型models.py

说明:我们自定义 用户表 和 用户Token表。关系是1对1关系

#自己定义的跟django自带的没有关系
class User(models.Model):
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)
 
#存放token表
class UserToken(models.Model):
    user = models.OneToOneField('User', models.CASCADE) #token跟user是1对1关系,一般都是放两张表做。
    token = models.CharField(max_length=64)
    
>python manage.py makemigrations
>python manage.py migrate
1
2
3
4
5
6
7
8
9
10
11
12

视图views.py

说明:我们必须要有一个登录视图,以及如何获取 md5值的设置。=> 编辑 views.py

# 获取MD5加密取值
def get_md5(user):
    ctime = str(time.time())
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    m.update(bytes(ctime, encoding='utf-8'))
    return m.hexdigest()

class LoginView(APIView):
    """用户登录"""
    authentication_classes = []
    permission_classes = []

    def post(self, request, *args, **kwargs):
        username = request.data.get("username")
        password = request.data.get("password")
        user_obj = User.objects.filter(username=username, password=password).first()
        if not user_obj:
            return Response({"code": 1, "message": "密码错误"})
        token = get_md5(username)  # 用账号去加密
        UserToken.objects.update_or_create(user=user_obj, defaults={"token": token})  # 不存在就创建,创建就更新defaults中的值
        return Response({"code": 0, "message": "success", "data": {"id": user_obj.id, "token": token}})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

路由urls.py

url(r"login/$", views.LoginView.as_view())  # 配置登录的路由
1

# b. 自定义认证编写(认证源码分析)

说明:我们都知道我们验证有三种方式:asicAuthentication, TokenAuthentication, SessionAuthentication。他们都是继承的谁呐?他们都是继承的是 BaseAuthentication。好啦,我们去看下BaseAuthentication的源码:Ctrl + BasicAuthentication => BaseAuthentication:
1

重写源码

class BaseAuthentication(object):
    """
    All authentication classes should extend BaseAuthentication.
    """
 
    def authenticate(self, request):   #哈哈,我们只要重写这个方法就行了,不重写这个方法就会报错
        """
        Authenticate the request and return a two-tuple of (user, token).
        """
        raise NotImplementedError(".authenticate() must be overridden.")
 
    def authenticate_header(self, request):
        """
        Return a string to be used as the value of the `WWW-Authenticate`
        header in a `401 Unauthenticated` response, or `None` if the
        authentication scheme should return `403 Permission Denied` responses.
        """
        pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# c. 自定义认证类

说明:继续编辑视图views.py文件,继承BaseAuthentication类,重写authenticate方法。

from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication

from .models import UserToken

class MyAuthtication(BaseAuthentication):
    def authenticate(self, request):
        # token = request.data.get("token")
        token = request.META.get('HTTP_AUTHORIZATION', None)
        user_obj = UserToken.objects.filter(token=token).first()
        if not user_obj:
            raise exceptions.AuthenticationFailed('用户未认证')
        return (user_obj.user, token)

    def authenticate_header(self, request):
        pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# d. 在视图中使用

全局

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.MyAuthtication',]
}
1
2
3

局部

class GameList(APIView):
    authentication_classes = [MyAuthtication, ]  # 方式二:
1
2

# 2.5 JWT 认证示例

6-7 认证和权限-DRF认证之jwt认证 (opens new window)

# 2.6 匿名用户(未登录用户)

  1. settings.py

    匿名用户就是设置request.user和request.auth为None

    REST_FRAMEWORK = {
        # 'DEFAULT_AUTHENTICATION_CLASSES': ['app02.utils.auth.FirstAuthtication', 'app02.utils.auth.Authtication'],
        'DEFAULT_AUTHENTICATION_CLASSES': ['app02.utils.auth.FirstAuthtication'],  # 匿名用户(因为我们在封装的时候什么都没有写,让它返回None)
        # 'UNAUTHENTICATED_USER': lambda: '匿名用户',
        'UNAUTHENTICATED_USER': None,
        'UNAUTHENTICATED_TOKEN': None,
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. app02.utils.auth.py

    class FirstAuthtication(object):
        def authenticate(self, request):
            print('匿名用户')
            pass  # pass返回的是None (搞成匿名用户的示例)
    
        def authenticate_header(self, request):
            pass
    
    1
    2
    3
    4
    5
    6
    7

# 3. 认证流程原理

dispatch开始

# 1.APIView下的dispatch

    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        # 获取的参数
        # 把获取的参数,经过initialize_request构建成新的request
        request = self.initialize_request(request, *args, **kwargs)
        # 获取原生request,request._request
        # 获取认证类的对象,request.authenticators
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 2.initialize_request  

 def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)

        return Request(  # 构建新的request
            request,
            parsers=self.get_parsers(),
            authenticators=self.get_authenticators(), # [BasicAuthentication(),]
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3.get_authenticators
def get_authenticators(self):
        """
        Instantiates and returns the list of authenticators that this view can use.
        """
        return [auth() for auth in self.authentication_classes]  # 遍历身份认证对象
1
2
3
4
5
6
# 4.perform_authentication 传入的对象进行身份认证 
def perform_authentication(self, request):  # 执行身份认证
    """
    Perform authentication on the incoming request.

    Note that if you override this and simply 'pass', then authentication
    will instead be performed lazily, the first time either
    `request.user` or `request.auth` is accessed.
    """
    request.user  # 进入封装的Respons方法
1
2
3
4
5
6
7
8
9
10
# 5.原生的request
@property
def user(self):
    """
    Returns the user associated with the current request, as authenticated
    by the authentication classes provided to the request.
    """
    if not hasattr(self, '_user'):
        with wrap_attributeerrors():
            # 获取认证对象,进行一步的认证
            self._authenticate()  # 进入认证
    return self._user
1
2
3
4
5
6
7
8
9
10
11
12
#  6.self._authenticate()、进入def _not_authenticated(self):方法,为None,或者有值
def _authenticate(self):
    """
    Attempt to authenticate the request using each authentication instance
    in turn.
    """
    # [BasicAuthentication对象,]
    for authenticator in self.authenticators:  # 遍历认证对象,执行认证方法
        try:
            # 执行认证类的authenticate方法
            # 1. 如果authenticate方法抛出异常,self_not_authenticate()执行
            # 2. 有返回值必须是元组:(request.user,request.auth)
            # 3. 返回None的话,下个认证来进行处理
            user_auth_tuple = authenticator.authenticate(self) # 执行这个对象的认证方法(认证是否以及登录),如果没有就报错
        except exceptions.APIException:
            self._not_authenticated()  # 没有进入_not_authenticated,返回对应的错误消息
            raise

        if user_auth_tuple is not None:  # 给响应的参数赋值
            self._authenticator = authenticator # 
            self.user, self.auth = user_auth_tuple  # 返回元组
            return  # 返回None下一个认证来处理

    self._not_authenticated()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 自定义认证类示例

(一定要记住先做认证在做权限)

class Authtication(object):
    def authenticate(self, request):
        token = request._request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed('用户未认证')
        return (token_obj.user, token_obj)  # 在rest fromwork内部会将这二个字段赋值给request,以供后续的使用(对应request.user,request.auth)

    def authenticate_header(self, request):
        pass

class OrderView(APIView):
    authentication_classes = [Authtication, ]  # 方式二:

    def get(self, request, *args, **kwargs):
        # 方式一:
        # token = request._request.GET.get('token')
        # if not token:
        #     raise exceptions.AuthenticationFailed('用户未认证')
        ret = {'code': 1000, 'message': 'ok!', 'data': None}
        try:
            ret['data'] = ORDER_DICT
        except Exception as e:
            ret['code'] = 1001
            ret['message'] = '找不到服务器'
        return JsonResponse(ret)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 4. 梳理

1. 使用 
				- 创建类:继承BaseAuthentication; 实现:authenticate方法
				- 返回值:
					- None,我不管了,下一认证来执行。
					- raise exceptions.AuthenticationFailed('用户认证失败') # from rest_framework import exceptions
					- (元素1,元素2)  # 元素1赋值给request.user; 元素2赋值给request.auth 
					
				- 局部使用
					from rest_framework.authentication import BaseAuthentication,BasicAuthentication
					class UserInfoView(APIView):
						"""
						订单相关业务
						"""
						authentication_classes = [BasicAuthentication,]
						def get(self,request,*args,**kwargs):
							print(request.user)
							return HttpResponse('用户信息')
				- 全局使用:
					REST_FRAMEWORK = {
						# 全局使用的认证类
						"DEFAULT_AUTHENTICATION_CLASSES":['app02.utils.auth.FirstAuthtication','app02.utils.auth.Authtication', ],
						# "UNAUTHENTICATED_USER":lambda :"匿名用户"
						"UNAUTHENTICATED_USER":None, # 匿名,request.user = None
						"UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None
					}
			2. 源码流程
				- dispatch
					- 封装request
						- 获取定义的认证类(全局/局部),通过列表生成时创建对象。
					- initial
						- perform_authentication
							request.user(内部循环....)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
编辑 (opens new window)
DRF类视图
权限

← DRF类视图 权限→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式