一、配置认证类
1.认证全局配置文件
经过认证的源码流程剖析,DRF的认证全局配置在api_setting中,以下是api_setings部分源码:
1
2
3
4
5
6
7
8
|
api_settings = APISettings( None , DEFAULTS, IMPORT_STRINGS) def reload_api_settings( * args, * * kwargs): setting = kwargs[ 'setting' ] if setting = = 'REST_FRAMEWORK' : #项目中settings.py的key api_settings. reload () setting_changed.connect(reload_api_settings) |
其中引用了django,settings.py中的REST_FRAMEWORK作为key作为配置,所以全局配置示例:
1
2
3
4
|
#全局认证配置 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES" :[ 'API.utils.auth.Authentication' ,] #其中写认证的类的路径,不要在views中,这里我放在了utils目录下auth.py中 } |
2.局部使用
局部某个视图不需要认证,则在视图类中加入authentication_classes=[]
1
|
authentication_classes = [] #authentication_classes为空,代表不需要认证 |
3.匿名用户配置:
1
2
3
4
|
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES" :[ 'API.utils.auth.Authentication' ,], #其中写认证的类的路径,不要在views中,这里我放在了utils目录下auth.py中 "UNAUTHENTICATED_USER": lambda:"匿名",#匿名用户配置,只需要函数或类的对应的返回值,对应request.user="匿名" "UNAUTHENTICATED_token" : None , #匿名token,只需要函数或类的对应的返回值,对应request.auth=None } |
二、内置认证类
1.BaseAuthentication
BaseAuthentication是django rest framework为我们提供了最基本的认证类,正如源码流程一样,该类中其中定义的两个方法authenticate和authenticate_header(认证失败返回的响应头),使用时候重写该两个方法进行认证,正如示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 |
2.其他认证类
1
2
3
4
5
|
##路径:rest_framework.authentication BasicAuthentication #基于浏览器进行认证 SessionAuthentication #基于django的session进行认证 RemoteUserAuthentication #基于django admin中的用户进行认证,这也是官网的示例 TokenAuthentication #基于drf内部的token认证 |
三、总结
1.自定义认证类:
继承BaseAuthentication,重写authenticate方法和authenticate_header(pass就可以),authenticate()方法需要有三种情况(返回元祖、出现异常、返回none)。
2.认证配置:
1
2
3
4
5
6
7
8
9
10
|
#全局认证 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES" :[ 'API.utils.auth.Authentication' ,] } #局部认证 authentication_classes = [BaseAuthentication,] #是某个视图不进行认证 authentication_classes = [] |
3.源码流程:
1.在django(CBV)中,客户端的发来的请求会执行视图类的as_view方法,而as_view方法中会执行dispacth方法,然后在根据请求的类型(反射)执行相应的方法(get、post等)。
2.使用django rest framework中的视图类需要继承APIView,请求到达视图类会执行视图类的as_view方法,而OrderView中没有as_view()方法,所以执行APIView的as_view()方法,
3.从APIView源码中可以看到APIView中as_view又执行了父类的as_view方法,在看看APIView的父类是View类,这恰好是django中的view视图类,
4.从View源码可以看出View类的as_view()方法执行流程:验证请求方法--->返回view函数名称(view函数会执行dispatch方法),一旦有请求进来执行view函数-->执行dispatch方法
5.当APIView的as_view方法执行了父类的as_view方法以后,请求进来会执行view方法,view方法中会执行dispatch方法,而Oderview没有dispatch方法,所以执行父类(APIView)的dispatch方法,
6.从APIView源码分析,执行APIView的dispatch方法时候会执行self.initialize_request方法,会对django原始的request进行封装。
7.self.initialize_request()源码分析,实例化Request()类,封装原始的request,authenticators(认证),执行self.get_authenticators(),到了这里就开始django rest framework的认证流程
8.self.get_authenticators()源码分析,采用列表生成式,循环self.authentication_classes,实例化其中的每一个类,返回列表,不难发现authentication_classes属性正式我们在认证的时候用到认证类列表,这里会自动寻找该属性进行认证。倘若我们的视图类没有定义认证方法呢?,当然django rest framework 已经给我们加了默认配置,如果我们没有定义会自动使用settings中的DEFAULT_AUTHENTICATION_CLASSES作为默认(全局),
9.继续分析APIView的dispatch方法,此时执行self.inital方法,并将封装过后的request对象(Reuqest)作为参数进行传递,
10.在self.inital方法中会执行self.perform_authentication方法,而self.perform_authentication方法用会执行request.user,此时的request是Request对象,所以需分析Request类中的user属性,
11.从源码分析,在Request对象中,user属性是一个属性方法,并会执行self._authentication方法,
12.从源码分析,Request对象的self._authentication中循环self.authenticators(该列表是由认证对象构成的[对象1,对象2]),并执行每一个对象中的authenticate方法返回tuple,同时对该过程其进行了异常捕捉,有异常将返回给用户,下面是异常验证逻辑:
如果有异常则执行self._not_authenticated()方法,继续向上抛异常。
如果有返回值必须是一个元组,分别赋值给self.user, self.auth(request.user和request.auth),并跳出循环。
如果返回None,则由下一个循环处理,如果都为None,则执行self._not_authenticated(),返回 (AnonymousUser,None)
13.当都没有返回值,就执行self._not_authenticated(),相当于匿名用户,没有通过认证,并且此时django会返回默认的匿名用户设置AnonymousUser,如需要单独设置匿名用户返回值,则编写需要写UNAUTHENTICATED_USER的返回值:
14.所以经过以上分析,我们需要进行认证时候,需要在每一个认证类中定义authenticate进行验证,并且需要返回元祖。
到此这篇关于django 认证类配置实现的文章就介绍到这了,更多相关django 认证类配置内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://juejin.cn/post/7027424194186985508