3月6日学习内容整理:restframework的认证补充

一、认证补充

1、昨天讲的源码流程(具体看昨天博客)

》1、URL路由匹配成功后首先执行as_view方法,实际上执行的是API的as_view,其中又用super方法执行V的as_view,再是执行V的view方法,再是执行dispatch方法,注意这里就会执行API中的dispatch方法如下第一图,

》2、首先是将传入的原生request重新赋值,调用API的initialize_request方法,得到一个Request对象如下第二图,这个request封装了两个属性如下第三图,request._request指的就是原生的request,request.authenticators则是一个列表,里面是SessionAuthentication BasicAuthentication 这两个类的实例对象,这两个类是restframework里默认的,就是用来做认证的类,这两个类是API中的authentication_classes参数里定义的

》3、将request重新封装后initialize_request函数结束后继续向下执行如下第一图,执行API的initial方法,在initial中执行self.perform_authentication(request)方法,在这个方法中运行request.user方法,这个request就是dispatch方法中重新封装的request也就是Request对象的user属性继而执行_authenticate方法,这个方法就会循环第2步中封装的request的authenticators属性,也就是存放着两个认证类的实例对象的列表,依次执行两个实例对象的authenticate方法,这个方法就是具体来做认证操作的

》4、API的initial方法执行完后,也就代表认证通过,继续向下就会利用反射去执行不同请求method对应的函数了如下第一图

 

2、认证函数的返回值

(1)在API中的dispatch中的initial方法中执行认证时,循环每个认证类执行authenticate方式时有三种返回值:

》返回None,代表继续下一个认证方法

》抛出异常,捕捉到后就会返回给前端,必须抛出AuthenticationFailed这个异常

》返回元组,restframework就会把这个元组中的第一个元素赋值给request.user属性,把第二个元素赋值给request.auth属性,这里的request就是API中的dispatch方法重新封装的Request对象,CBV中的视图得到的request都是重新封装后的Request对象

注意注意注意:::若所有的认证类的authenticate函数都没有返回值,那么request.user的默认值就是一个匿名对象AnonymousUser,request.auth的默认值就是None

 

3、从视图的角度分为全局和局部使用认证功能

(1)局部使用:

》在自定义view类中定义好authentication_classes列表参数,里面存放自定义认证类,这样rest在找认证类就不会去找默认的了,在自定义认证类中必须写authenticate认证函数和authenticate_header方法

注意注意:::

1)authenticate_header方法是认证失败时给浏览器的返回的响应头,这个一般不写就pass,但是必须要有

2)若不想进行验证,就把authentication_classes设置为空列表就可以了

(2)全局使用:意味着CBV中所有的视图都要进行认证

因为rest在找认证类的时候是去配置文件中找的,所以我们要从配置文件中设置全局的认证类

REST_FRAMEWORK = {
# 全局使用的认证类
"DEFAULT_AUTHENTICATION_CLASSES":
# 是一个列表,每个元素是认证类的路径,定义了哪几个认证类就代表CBV中所有的视图都要经过这几个认证类的认证
['api.utils.auth.FirstAuthtication','api.utils.auth.Authtication', ],

# 下面这两个字段是定义当认证函数没有返回值时request.user的默认值,可以是lambda表达式的结果或者直接定义为None
"UNAUTHENTICATED_USER":lambda :"匿名用户"
"UNAUTHENTICATED_USER":None, # 匿名,request.user = None
# 下面这个字段是定义认证函数没有返回值时request.auth的默认值,也可以写lambda表达式
"UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None
}

 

4、rest的内置认证类

基于内置的认证类,我们在自定义认证类的时候可以继承这个BaseAuthentication内置类,代码入下第二图,这样我们就不用写authenticate_header方法了,但是必须写authenticate方法,否则按内置类的处理就会抛出异常了

# 都在这里面
from rest_framework.authentication import BaseAuthentication
class BaseAuthentication(object):
  
    def authenticate(self, request):
        
        raise NotImplementedError(".authenticate() must be overridden.")

    def authenticate_header(self, request):
       
        pass

 

posted @ 2018-03-06 16:16  九二零  阅读(126)  评论(0编辑  收藏  举报