Django休息框架中无效令牌认证的自定义响应

时间:2015-10-19 14:47:33

标签: django django-rest-framework django-authentication

对于下面这段代码,我想返回一个对应于用户是否经过身份验证的布尔值。

class UserAuthenticatedView(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (AllowAny,)
    def get(self, request, format=None):
        is_authenticated = request.user.is_authenticated()
        resp = {'is_authenticated': is_authenticated}
        return Response(resp, content_type="application/json", status=status.HTTP_200_OK)

但是,对于无效令牌,控件甚至不会进入get方法,因为我无法自定义响应。在这种情况下,我得到了回复:{'detail': 'invalid token'}, 有关如何自定义无效令牌响应的任何想法吗?

2 个答案:

答案 0 :(得分:4)

您可以创建CustomTokenAuthentication类并覆盖authenticate_credentials()方法,以便在令牌无效的情况下返回自定义响应。

class CustomTokenAuthentication(TokenAuthentication):

    def authenticate_credentials(self, key):
        try:
            token = self.model.objects.select_related('user').get(key=key)
        except self.model.DoesNotExist:
            # modify the original exception response
            raise exceptions.AuthenticationFailed('Custom error message') 

        if not token.user.is_active:
            # can also modify this exception message
            raise exceptions.AuthenticationFailed('User inactive or deleted')

        return (token.user, token)

执行此操作后,在DRF设置或基于每个视图/视图集的基础上定义此自定义令牌认证类。

另一种选择是创建custom exception handler.在此,您可以检查引发的异常是否为AuthenticationFailed类型,并且异常消息为'invalid token'。在那里你可以修改异常消息(也可以查看这个官方DRF example)。

答案 1 :(得分:3)

这对我有用:

自定义身份验证类:

class MyAuthentication(authentication.TokenAuthentication):
    def authenticate_credentials(self, key):
        try:
            token = self.model.objects.select_related('user').get(key=key)
        except self.model.DoesNotExist:
            return (None, '')

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))

        return (token.user, token)

查看课程:

class UserAuthenticatedView(APIView):
    authentication_classes = (MyAuthentication,)
    permission_classes = (AllowAny,)

    def get(self, request, format=None):
        is_authenticated = False
        if request.user and request.user.is_authenticated():
            is_authenticated = True
        resp = {'is_authenticated': is_authenticated}
        return Response(resp, content_type="application/json", status=status.HTTP_200_OK)