DRF源码学习-Authentication
原创2022年1月31日
认证组件Authentication
All authentication classes should extend BaseAuthentication. 所有认证类都应该继承于BaseAuthentication —— 来自BaseAuthentication类注释
1.BaseAuthentication

BaseAuthentication为认证类的基类,其中有两个方法:
- authenticate - 这个方法必须被子类实现,用于检测认证是否通过,且必须返回元祖(user, token),值得注意的一点,当方法返回None的时候会跳过此验证,继续下一个验证,如果想认证不通过,则需要抛出AuthenticationFailed异常。
 
- authenticate_header - 这个方法子类也可以不去覆盖,默认情况下,当授权未通过,展示返回headers中key为WWW-Authenticate的value
 
2.编写自己的认证组件
在这里我直接最简易的判断header来检测认证
class MyAuthentication(BaseAuthentication):
    # 实现父类中的authenticate方法
    def authenticate(self, request):
        if request.META.get("HTTP_AUTHORIZATION") == 'miclon':
            return (None, None)
        raise AuthenticationFailed('认证不通过')
        
    def authenticate_header(self, request):
        return "get out"
当启用header的时候:  当关闭此header的时候:
 当关闭此header的时候:  同时可以在返回header中观察到:
 同时可以在返回header中观察到: 
3.认证组件原理
在APIView类中,认证组件读取Django设置项中DEFAULT_AUTHENTICATION_CLASSES的列表作为默认认证类
class APIView(View):
	……
	authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    ……
所以,当继承APIView的子类,使用覆盖authentication_classes的方式,即可自定义该子类的认证类
class TestView(APIView):
    authentication_classes = [MyAuthentication]
    def get(self, request):
        return JsonResponse({"result": "success"})
又由于APIView是继承自Django的View,Django的View是由dispatch方法来调度的,APIView重写了此方法,在初始化获取request实例的时候,将子类中所有的认证类传递给Request类

来看看Request类干了什么事。  不难看出,它for循环遍历了所有认证组件,分别去执行其中的
 不难看出,它for循环遍历了所有认证组件,分别去执行其中的authenticate方法,当出现APIException异常的时候抛出错误。 再回过头看看,当我们认证不允许通过的时候,抛出AuthenticationFailed的异常,而它实际上是继承自APIException,且覆盖了出错的状态码为401 
以上就是针对DjangoRestFramework中认证组件的简要解读。
Loading...