zoukankan      html  css  js  c++  java
  • Django rest framework----认证

    Django rest framework----认证

    先了解的一些知识

    理解下面两个知识点非常重要,django-rest-framework源码中到处都是基于CBV和面向对象的封装

    (1)面向对象封装的两大特性

    把同一类方法封装到类中
    
    将数据封装到对象中

    (2)CBV

    CBV(class base views) 就是在视图里使用类处理请求。  对应的还有 FBV(function base views) 就是在视图里使用函数处理请求。

    基于反射实现根据请求方式不同,执行不同的方法

    原理:url-->view方法-->dispatch方法(反射执行其它方法:GET/POST/PUT/DELETE等等)

    CBV(class base views) 就是在视图里使用类处理请求。

    Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

    1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

    如果我们要写一个处理GET方法的view,用函数FBV写的话是下面这样。

    from django.http import HttpResponse
      
    def my_view(request):
         if request.method == 'GET':
                return HttpResponse('OK')

    如果用class-based view写的话,就是下面这样

    from django.http import HttpResponse
    from django.views import View
      
    class MyView(View):
    
          def get(self, request):
                return HttpResponse('OK')

    Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

    在url中,就这么写:

    # urls.py
    from django.conf.urls import url
    from myapp.views import MyView
      
    urlpatterns = [
         url(r'^index/$', MyView.as_view()),
    ]

    类的属性可以通过两种方法设置,第一种是常见的Python的方法,可以被子类覆盖。

    from django.http import HttpResponse
    from django.views import View
      
    class GreetingView(View):
        name = "yuan"
        def get(self, request):
             return HttpResponse(self.name)
      
    # You can override that in a subclass
      
    class MorningGreetingView(GreetingView):
        name= "alex"

    第二种方法,你也可以在url中指定类的属性:

    在url中设置类的属性Python

    urlpatterns = [
       url(r'^index/$', GreetingView.as_view(name="egon")),
    ]

    要理解django的class-based-view(以下简称cbv),首先要明白django引入cbv的目的是什么。在django1.3之前,generic view也就是所谓的通用视图,使用的是function-based-view(fbv),亦即基于函数的视图。有人认为fbv比cbv更pythonic,窃以为不然。python的一大重要的特性就是面向对象。而cbv更能体现python的面向对象。cbv是通过class的方式来实现视图方法的。class相对于function,更能利用多态的特定,因此更容易从宏观层面上将项目内的比较通用的功能抽象出来。关于多态,不多解释,有兴趣的同学自己Google。总之可以理解为一个东西具有多种形态(的特性)。cbv的实现原理通过看django的源码就很容易明白,大体就是由url路由到这个cbv之后,通过cbv内部的dispatch方法进行分发,将get请求分发给cbv.get方法处理,将post请求分发给cbv.post方法处理,其他方法类似。怎么利用多态呢?cbv里引入了mixin的概念。Mixin就是写好了的一些基础类,然后通过不同的Mixin组合成为最终想要的类。

    所以,理解cbv的基础是,理解Mixin。Django中使用Mixin来重用代码,一个View Class可以继承多个Mixin,但是只能继承一个View(包括View的子类),推荐把View写在最右边,多个Mixin写在左边。

     mixin模式

    class X(object):
      def f(self):
        print( 'x')
    
    class A(X):
      def f(self):
        print('a')
    
      def extral(self):
        print('extral a')
    
    class B(X):
      def f(self):
        print('b')
    
      def extral(self):
        print( 'extral b')
    
    class C(A, B, X):
      def f(self):
        super(C, self).f()
        print('c')
    
    print(C.mro())
    
    c = C()
    c.f()
    c.extral()

    这样做也可以输出结果

    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.X'>, <class 'object'>] # 继承的顺序是 A-->B-->X-->object 这了的object在python3中是一切类的基类,包括object类本身。
    a
    c
    extral a # 虽然类C中没有实现接口extral(),却调用了父类A中的extral()方法

    这样的继承虽然可以实现功能,但是有一个很明显的问题,那就是在面向对象中,一定要指明一个类到底是什么。也就是说,如果我想构造一个类,假如是Somthing,那么我想让这个类实现会飞,会游泳,会跑,三种行为,我可以这样做,同时继承,鸟,鱼,马三个类,像这样

    class Bird:
      def fly(self):
        print('fly')
    
    class Fish:
      def swim(self):
        print('swim')
        
    class Horse:
      def run(self):
        print('run')
        
        
    class Something(Bird, Fish, Horse):
      pass
    
    
    s = Something()
    s.fly()
    s.swim()
    s.run()

    输出

    fly
    swim
    run

    可是实现会跑,会飞,会游泳的三种行为,但是这个类到底是什么,是鱼,是马,还是鸟,也就是说不知道Something到底是个什么类。为了解决这个问题,我们可以引用mixin模式。改写如下

    class BirdMixin:
      def fly(self):
        print('fly')
    
    class FishMixin:
      def swim(self):
        print('swim')
        
    class Horse:
      def run(self):
        print('run')
        
        
    class Something(BirdMixin, FishMixin, Horse):
      pass

    这样就解决了上面的问题,也许你会发现,这其实没有什么变化,只是在类的命名加上了以Mixin结尾,其实这是一种默认的声明,告诉你,Something类其实是一种马,父类是HorseHorse,继承其他两个类,只是为了调用他们的方法而已,这种叫做mixin模式,在drf的源码种会用到

    例如drf中的generics 路径为rest_framework/generics.py

    class CreateAPIView(mixins.CreateModelMixin,
              GenericAPIView):
      pass
    
    
    class ListAPIView(mixins.ListModelMixin,
             GenericAPIView):
      pass
    
    
    class RetrieveAPIView(mixins.RetrieveModelMixin,
               GenericAPIView):
      pass

    相当于每多一次继承,子类可调用的方法就更多了。

    简单实例

    settings

    先创建一个project和一个app(我这里命名为api)

    首先要在settings的app中添加

    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',
        'api',
        'corsheaders',  # 解决跨域问题 修改1
    ]

    urls

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url
    
    from api.views import AuthView
    from api.views import OrderView,UserInfoView
    from api.appview.register import registerView
    from django.views.generic.base import TemplateView  # 1、增加该行
    
    
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path(r'',TemplateView.as_view(template_name='index.html')),  #2、 增加该行
        url(r'^api/v1/auth/$', AuthView.as_view()),  # 登录
        url(r'^api/v1/order/$', OrderView.as_view()),  # 用户认证
        url(r'^api/v1/info/',UserInfoView.as_view()),     # 用户权限
        url(r'^home/register/$', registerView.as_view()),   # 注册
    ]

    models

    一个保存用户的信息

    一个保存用户登录成功后的token

    from django.db import models
    
    # Create your models here.
    
    class User(models.Model):
        USER_TYPE = (
            (1, '普通用户'),
            (2, 'VIP'),
            (3, 'SVIP')
        )
    
        username = models.CharField(max_length=32,unique=True)
        password = models.CharField(max_length=32)
        age = models.CharField(max_length=32)
        e_mail = models.EmailField()
        user_type = models.IntegerField(choices=USER_TYPE)
        create_time = models.DateTimeField(auto_now_add=True)
        update_time = models.DateTimeField(auto_now=True)
    
        def __str__(self):
            return 'username: %s,password: %s' %(self.username,self.password)
    
            # return 'username: {},password: {}'.format(self.username, self.password)
        class Meta:
            db_table = 'user'
            verbose_name = verbose_name_plural = '用户信息表'
    
    class userToken(models.Model):
        user = models.OneToOneField(to='User',on_delete=models.DO_NOTHING)
        # 注意:在数据中关联字段名称叫user_id
        token = models.CharField(max_length=60)
        """定义每个数据对象的显示信息"""
        def __unicode__(self):      # return self.user   使用 def __str__(self):报错 , 使用 __unicode__ 就 OK了。
            return  self.user
    
        """定义每个数据对象的显示信息"""
        def __str__(self):
            return self.token     # 这个返回值是干什么的? 这里 不能写 user 因为user 对应的是 user_id 是int 类型,服务端会报错。
    
        class Meta:
            db_table =  'userToken'
            verbose_name = verbose_name_plural = '用户token表'
    
    
    
    
    #    def __str__(self):   的作用
    #         return 'username: %s,password: %s' %(self.username,self.password)
    
    # 在终端中执行  python manage.py shell
    # from api.models import User
    # User.objects.get(id=1)
    # 即可返回如下 信息,
    # <User: username: wang,password: 123456>

    views

    用户登录(返回token并保存到数据库)

    from django.shortcuts import render
    
    # Create your views here.
    
    import time
    from api import models
    from django.http import JsonResponse
    from rest_framework.views import APIView
    from rest_framework.request import Request
    from rest_framework import exceptions
    from rest_framework.authentication import BasicAuthentication
    from django.shortcuts import render,HttpResponse
    
    from api.utils.permission import SVIPPermission,MyPermission
    
    
    
    ORDER_DICT = {
    
        1:{
            'name':'apple',
            'price':15
        },
        2:{
            'name':'orange',
            'price':30
        }
    }
    
    
    
    def md5(user):
        import hashlib
        import time
        ctime = str(time.time())
        print(ctime)
        m = hashlib.md5(bytes(user,encoding='utf-8'))
        print(m)
        m.update(bytes(ctime,encoding='utf-8'))
        print(m)
        usertoken = m.hexdigest()
        print(usertoken)
    
        return usertoken
    
    
    
    class AuthView(APIView):
    
        authentication_classes = []  # 里面为空,代表不需要认证
        permission_classes = []
        def post(self,request,*args,**kwargs):
            print('参数',request)
    
            ret = {'code':1000,'msg':None,'token':None}
            try:
                # 参数是datadict 形式
                usr = request.data.get('username')
                pas = request.data.get('password')
    
                # usr = request._request.POST.get('username')
                # pas = request._request.POST.get('password')
    
                # usr = request.POST.get('username')
                # pas = request.POST.get('password')
    
                print(usr)
                print(pas)
                # obj = models.User.objects.filter(username='yang', password='123456').first()
                obj = models.User.objects.filter(username=usr,password=pas).first()
                # obk =models.userToken.objects.filter(token='9c979c316d4ea42fd998ddf7e8895aa4').first()
                # print(obk.token)
                print('******')
                print(obj)
                print(type(obj))
                print(obj.username)
                print(obj.password)
                if not obj:
                    ret['code'] = '1001'
                    ret['msg'] = '用户名或者密码错误'
                    return JsonResponse(ret)
                    # 里为了简单,应该是进行加密,再加上其他参数
                # token = str(time.time()) + usr
                token = md5(usr)
                print(token)
                models.userToken.objects.update_or_create(user=obj, defaults={'token': token})
                ret['token'] = token
                ret['msg'] = '登录成功'
                #ret['token'] = token
            except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
            return JsonResponse(ret)

    注册模块

    api/appview/register.py

    # FileName : register.py
    # Author   : Adil
    # DateTime : 2019/7/19 5:52 PM
    # SoftWare : PyCharm
    
    from api import models
    from django.http import JsonResponse
    from rest_framework.views import APIView
    import time
    from api.common.DBHandle import DataBaseHandle
    import datetime
    
    
    
    class registerView(APIView):
    
        def changeinfo(self,*args):
            pass
    
    
        def post(self,request,*args,**kwargs):
            print('参数', request)
            print(request.data)
            ret = {'code': 1000, 'msg': None}
            try:
                # 参数是datadict 形式
                usr = request.data.get('username')
                pas = request.data.get('password')
                age = request.data.get('age')
                user_type = request.data.get('user_type')
                e_mail = request.data.get('email')
    
                localTime = time.localtime(time.time())
                tmp_time = time.strftime("%Y-%m-%d %H:%M:%S", localTime)
                print(usr)
                print(tmp_time)
                print(e_mail)
                ct = tmp_time
                ut = tmp_time
                host = '127.0.0.1'
                username = 'username'
                password = 'password'
                database = 'dbname'
                port = 3306
                # 实例化 数据库 连接
                dbcon = DataBaseHandle(host, username, password, database, port)
    
                sql = "select username from user where username = '%s' " %(usr)
    
                l1 = dbcon.selectDb(sql)
                print(age)
                if l1==1:
                    ret['msg'] = '用户已存在!'
    
                else:
                    # obj = models.User.objects.filter(username=usr, password=pas).first()
                    #print(obj.age)
                    # models.User.objects.update_or_create(username='yang', password='123456',age='19')
                    print('else')
                    print(usr,pas,age,e_mail,ct,ut)
                    #sql = "insert into user(username,password,age,e_mail) values ('%s','%s','%s','%s')" % (usr, pas,age,e_mail)
                    # models.User.objects.update_or_create(username=usr, password=pas, age=age,e_mail= e_mail,create_time=ct,update_time=ut)
                    # obj = models.User.objects.filter(username='yang', password='123456').first()
                    # tt = dbcon.insertDB(sql)
                    user = models.User(username=usr, password=pas, age=age,user_type=user_type,e_mail= e_mail)
                    user.save()
    
                    print(models.User.objects.all())
                    print('*******')
                    ret['msg'] = '注册成功'
                    # if tt==1:
                    #     ret['msg'] = '注册成功'
    
            except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
            return JsonResponse(ret)

    利用postman发请求

    注册

    注册成功后,数据存入user表

    登录模块 

     

     userToken数据表

    添加认证

     基于上面的例子,添加一个认证的类

    urls

    path('api/v1/order/',OrderView.as_view()),

    views

     

    from django.shortcuts import render
    
    # Create your views here.
    
    import time
    from api import models
    from django.http import JsonResponse
    from rest_framework.views import APIView
    from rest_framework.request import Request
    from rest_framework import exceptions
    from rest_framework.authentication import BasicAuthentication
    from django.shortcuts import render,HttpResponse
    
    from api.utils.permission import SVIPPermission,MyPermission
    
    
    
    ORDER_DICT = {
    
        1:{
            'name':'apple',
            'price':15
        },
        2:{
            'name':'orange',
            'price':30
        }
    }
    
    
    
    def md5(user):
        import hashlib
        import time
        ctime = str(time.time())
        print(ctime)
        m = hashlib.md5(bytes(user,encoding='utf-8'))
        print(m)
        m.update(bytes(ctime,encoding='utf-8'))
        print(m)
        usertoken = m.hexdigest()
        print(usertoken)
    
        return usertoken
    
    
    
    class AuthView(APIView):
    
        authentication_classes = []  # 里面为空,代表不需要认证
        permission_classes = []
        def post(self,request,*args,**kwargs):
            print('参数',request)
    
            ret = {'code':1000,'msg':None,'token':None}
            try:
                # 参数是datadict 形式
                usr = request.data.get('username')
                pas = request.data.get('password')
    
                # usr = request._request.POST.get('username')
                # pas = request._request.POST.get('password')
    
                # usr = request.POST.get('username')
                # pas = request.POST.get('password')
    
                print(usr)
                print(pas)
                # obj = models.User.objects.filter(username='yang', password='123456').first()
                obj = models.User.objects.filter(username=usr,password=pas).first()
                # obk =models.userToken.objects.filter(token='9c979c316d4ea42fd998ddf7e8895aa4').first()
                # print(obk.token)
                print('******')
                print(obj)
                print(type(obj))
                print(obj.username)
                print(obj.password)
                if not obj:
                    ret['code'] = '1001'
                    ret['msg'] = '用户名或者密码错误'
                    return JsonResponse(ret)
                    # 里为了简单,应该是进行加密,再加上其他参数
                # token = str(time.time()) + usr
                token = md5(usr)
                print(token)
                models.userToken.objects.update_or_create(user=obj, defaults={'token': token})
                ret['token'] = token
                ret['msg'] = '登录成功'
                #ret['token'] = token
            except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
            return JsonResponse(ret)
    
    
    
    class Authentication(APIView):
        '''认证'''
    
        def authenticate(self,request):
            token = request._request.GET.get('token')
            print(token)
            token_obj = models.userToken.objects.filter(token=token).first()
            if not token_obj:
                raise exceptions.AuthenticationFailed('用户认证失败')
            # 在rest framework内部会将这两个字段赋值给request,以供后续操作使用
            return (token_obj.user, token_obj)
    
        def authenticate_header(self, request):
            pass
    
    
    class OrderView(APIView):
        '''订单业务'''
    
        authentication_classes = [Authentication,]    #添加认证
    
        # permission_classes = []
        def get(self,request,*args,**kwargs):
            print("~~~~~~")
            print(request.user)
            print(request.auth)
            print("~~~~~~")
            ret = {'code':1000,'msg':None,'data':None}
            try:
                ret['data'] = ORDER_DICT
            except Exception as e:
                pass
            return JsonResponse(ret)

    用postman发get请求

    请求的时候没有带token,可以看到会显示“用户认证失败”

    加上token重新请求

    以上是简单的局部认证。下面介绍一下全局认证

    全局配置方法:

    api文件夹下面新建文件夹utils,再新建auth.py文件,里面写上认证的类

    auth.py

    # api/utils/auth.py
    
    from rest_framework import exceptions
    from api import models
    
    
    class Authentication(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('用户认证失败')
            #在rest framework内部会将这两个字段赋值给request,以供后续操作使用
            return (token_obj.user,token_obj)
    
        def authenticate_header(self, request):
            pass

     settings.py

    #设置全局认证
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.Authentication',],   #里面写你的认证的类的路径
    }

    在settings里面设置的全局认证,所有业务都需要经过认证,如果想让某个不需要认证,只需要在其中添加下面的代码:

    authentication_classes = []    #里面为空,代表不需要认证
    from django.shortcuts import render
    
    # Create your views here.
    
    import time
    from api import models
    from django.http import JsonResponse
    from rest_framework.views import APIView
    from rest_framework.request import Request
    from rest_framework import exceptions
    from rest_framework.authentication import BasicAuthentication
    from django.shortcuts import render,HttpResponse
    
    from api.utils.permission import SVIPPermission,MyPermission
    
    
    
    ORDER_DICT = {
    
        1:{
            'name':'apple',
            'price':15
        },
        2:{
            'name':'orange',
            'price':30
        }
    }
    
    
    
    def md5(user):
        import hashlib
        import time
        ctime = str(time.time())
        print(ctime)
        m = hashlib.md5(bytes(user,encoding='utf-8'))
        print(m)
        m.update(bytes(ctime,encoding='utf-8'))
        print(m)
        usertoken = m.hexdigest()
        print(usertoken)
    
        return usertoken
    
    
    
    class AuthView(APIView):
    
        authentication_classes = []  # 里面为空,代表不需要认证
        permission_classes = []
        def post(self,request,*args,**kwargs):
            print('参数',request)
    
            ret = {'code':1000,'msg':None,'token':None}
            try:
                # 参数是datadict 形式
                usr = request.data.get('username')
                pas = request.data.get('password')
    
                # usr = request._request.POST.get('username')
                # pas = request._request.POST.get('password')
    
                # usr = request.POST.get('username')
                # pas = request.POST.get('password')
    
                print(usr)
                print(pas)
                # obj = models.User.objects.filter(username='yang', password='123456').first()
                obj = models.User.objects.filter(username=usr,password=pas).first()
                # obk =models.userToken.objects.filter(token='9c979c316d4ea42fd998ddf7e8895aa4').first()
                # print(obk.token)
                print('******')
                print(obj)
                print(type(obj))
                print(obj.username)
                print(obj.password)
                if not obj:
                    ret['code'] = '1001'
                    ret['msg'] = '用户名或者密码错误'
                    return JsonResponse(ret)
                    # 里为了简单,应该是进行加密,再加上其他参数
                # token = str(time.time()) + usr
                token = md5(usr)
                print(token)
                models.userToken.objects.update_or_create(user=obj, defaults={'token': token})
                ret['token'] = token
                ret['msg'] = '登录成功'
                #ret['token'] = token
            except Exception as e:
                ret['code'] = 1002
                ret['msg'] = '请求异常'
            return JsonResponse(ret)
    
    class OrderView(APIView):
        '''订单业务'''
    
        # authentication_classes = []
    
        # permission_classes = []
        def get(self,request,*args,**kwargs):
            print("~~~~~~")
            print(request.user)
            print(request.auth)
            print("~~~~~~")
            ret = {'code':1000,'msg':None,'data':None}
            try:
                ret['data'] = ORDER_DICT
            except Exception as e:
                pass
            return JsonResponse(ret)

    再测试一下我们的代码

    不带token发请求

    带token发请求 

     

    drf的内置认证

     rest_framework里面内置了一些认证,我们自己写的认证类都要继承内置认证类 "BaseAuthentication"

    BaseAuthentication源码:

    class BaseAuthentication(object):
        """
        All authentication classes should extend BaseAuthentication.
        """
    
        def authenticate(self, request):
            """
            Authenticate the request and return a two-tuple of (user, token).
            """
            #内置的认证类,authenticate方法,如果不自己写,默认则抛出异常
            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.
            """
            #authenticate_header方法,作用是当认证失败的时候,返回的响应头
            pass

    修改自己写的认证类

    自己写的Authentication必须继承内置认证类BaseAuthentication 

    # FileName : auth.py
    # Author   : Adil
    # DateTime : 2019/7/30 4:29 PM
    # SoftWare : PyCharm
    
    from rest_framework import exceptions
    from api import models
    from rest_framework.authentication import BaseAuthentication
    
    
    class Authentication(BaseAuthentication):
        '''用于用户登录验证'''
        def authenticate(self,request):
            # token = request._request.GET.get('token')
            token = request.GET.get('token') #  同 request._request.GET.get('token')
            # token = request.query_params.get("token")  # 同request.GET.get("token")
            print('***')
            print(token)
            token_obj = models.userToken.objects.filter(token=token).first()
            print(token_obj)
            if not token_obj:
                raise exceptions.AuthenticationFailed('用户认证失败')
            #在rest framework内部会将这两个字段赋值给request,以供后续操作使用
            return (token_obj.user,token_obj)     # 这两个返回值分别对应 models.py 中 userToken 的user和 token
    
        def authenticate_header(self, request):
            pass

    其它内置认证类

    rest_framework里面还内置了其它认证类,我们主要用到的就是BaseAuthentication,剩下的很少用到

     

    总结

    自己写认证类方法梳理

     (1)创建认证类

    • 继承BaseAuthentication    --->>1.重写authenticate方法;2.authenticate_header方法直接写pass就可以(这个方法必须写)

    (2)authenticate()返回值(三种)

    • None ----->>>当前认证不管,等下一个认证来执行
    • raise exceptions.AuthenticationFailed('用户认证失败')       # from rest_framework import exceptions
    •  有返回值元祖形式:(元素1,元素2)      #元素1复制给request.user;  元素2复制给request.auth

     (3)局部使用

    • authentication_classes = [BaseAuthentication,]

    (4)全局使用

    #设置全局认证
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.Authentication',]
    }

    源码流程

    --->>dispatch

        --封装request

           ---获取定义的认证类(全局/局部),通过列表生成式创建对象 

         ---initial

           ----peform_authentication

             -----request.user   (每部循环创建的对象)

     
  • 相关阅读:
    HTML5程序设计--SVG
    visual studio 2012 Github
    排序算法--鸡尾酒排序
    排序算法--归并排序
    排序算法--冒泡排序
    排序算法---插入排序
    外语学习的真实方法及误区
    学习新东西的唯一方法
    如何做好一个面试官——之学习篇
    求职者和面试官如何做好电话面试
  • 原文地址:https://www.cnblogs.com/BlueSkyyj/p/11275177.html
Copyright © 2011-2022 走看看