Django 休息框架中无效令牌身份验证的自定义响应
Custom response for invalid token authentication in Django rest framework
对于下面的代码,我想 return 一个布尔值,对应于用户是否已通过身份验证。
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'}
,
知道如何自定义无效令牌的响应吗?
您可以创建 CustomTokenAuthentication
class 并将 authenticate_credentials()
方法覆盖为 return 自定义响应以防令牌无效。
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 设置中或在 per-view/viewset 基础上定义此自定义令牌身份验证 class。
另一种选择是创建 custom exception handler. In that, you can check if the exception raised was of type AuthenticationFailed
and the exception message is 'invalid token'
. There you can modify the exception message (also check this official DRF example)。
这对我有用:
自定义身份验证class:
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:
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)
对于下面的代码,我想 return 一个布尔值,对应于用户是否已通过身份验证。
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'}
,
知道如何自定义无效令牌的响应吗?
您可以创建 CustomTokenAuthentication
class 并将 authenticate_credentials()
方法覆盖为 return 自定义响应以防令牌无效。
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 设置中或在 per-view/viewset 基础上定义此自定义令牌身份验证 class。
另一种选择是创建 custom exception handler. In that, you can check if the exception raised was of type AuthenticationFailed
and the exception message is 'invalid token'
. There you can modify the exception message (also check this official DRF example)。
这对我有用:
自定义身份验证class:
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:
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)