天天看点

django-restframework之接口全局认证

上篇文章我们讲到了接口认证,但是还没有讲完,现在我们继续完善这方面的知识

上篇文章所做的接口认证,是针对单个接口进行的

如果要做我们所有的接口都需要进行接口认证呢?

于是乎,我们可以实现一个全局的接口认证,并且非常容易

就是在settings中做一下配置就行了

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES':(
        'API.auth_classes.UserAuth',
    )
}
           

auth_classes是我为认证类专门建的一个.py文件

django-restframework之接口全局认证

这时候,在调用底层认证代码的时候,默认就会执行我们给他指定好的认证类UserAuth

在代码中的authentication_classes 就可以注释掉了

class BookView(viewsets.ModelViewSet):
    # authentication_classes = [UserAuth]
    queryset = Book.objects.all()
    serializer_class = BookSerialize
           

然后再次测试结果,不加token进行访问

django-restframework之接口全局认证

效果一样

好了,全局认证就先讲到这了

大家有没有注意到

在写认证类的时候,是不是感觉有一段代码是多余的

def authenticate_header(self,request):
    pass
           

这段代码并不能删,不信你试试

但是每次写验证类都要带上这段代码感觉很不舒服

我们可以这样做

from rest_framework.authentication import BaseAuthentication
class UserAuth(BaseAuthentication):
    def authenticate(self,request):
        token = request.query_params.get('token')
        try:
            token = UserToken.objects.get(token=token)
            return token.user,token.token
        except Exception:
            raise APIException('认证不通过')
           

继承BaseAuthentication就可以不需要写那段冗余的代码了

为什么呢?来看看源码

class BaseAuthentication:
    """
    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
           

因为它已经帮我们写好了嚯嚯嚯嚯

最后给大家说一下一个要注意的地方

在认证类的 return token.user.username,token.token时

返回的值一定要有token等信息,帮助记住用户身份以及状态