我很难弄清楚当数据库因为某种原因删除了令牌时如何返回401。
让我解释一下。
我的常规设置使用SessionAuthentication和TokenAuthentication scheme。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_FILTER_BACKENDS': (
'rest_framework.filters.DjangoFilterBackend',
),
'DATETIME_FORMAT': '%a, %d %b %Y %H:%M:%S %z',
'DATETIME_INPUT_FORMATS': ['iso-8601', '%Y-%m-%d %H:%M:%S', '%a, %d %b %Y %H:%M:%S %z'],
'DATE_FORMAT': '%Y-%m-%d',
'DATE_INPUT_FORMATS': ['%Y-%m-%d', '%m/%d/%YYYY'],
'PAGE_SIZE': 20
}
我有一个生成Auth Token的视图,如下所示:
class AcmeObtainAuthToken(APIView):
throttle_classes = ()
permission_classes = ()
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
renderer_classes = (renderers.JSONRenderer,)
serializer_class = AcmeAuthTokenSerializer
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.context = {'request': self.request}
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key,
'school': school,
'user': user.id})
obtain_auth_token = AcmeObtainAuthToken.as_view()
我的问题是,当存储在db中的令牌由于某种原因而消失并且客户端发送令牌时,当我需要401时,我得到403.
看docs这真是神秘:
将使用的响应类型取决于身份验证方案。尽管可以使用多种认证方案,但是可以仅使用一种方案来确定响应的类型。在确定响应类型时使用视图上设置的第一个认证类。
它说它取决于但是如何?没有给出一个例子......有点混淆DRF如何在这里引起它的魔力......
答案 0 :(得分:2)
403是您应该在该实例中获得的响应。看看this link:
服务器理解请求,但拒绝履行请求。授权无效,请求不应重复。
从本质上讲,客户端提出了正确的请求,但令牌丢失,因此禁止访问(403)。
如果您确实想回复401错误,可以在BloowatchObtainAuthToken
视图中尝试以下内容:
class BloowatchObtainAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
response = super(BloowatchObtainAuthToken, self).post(request, *args, **kwargs)
try:
token = Token.objects.get(user=request.user) # or what you are validating against
other stuff here...
except Token.DoesNotExist:
return Response({'error': 'Token does not exist'}, status=401)
答案 1 :(得分:0)
我们可以重写restframework的exception_handler
在您的身份验证功能中:
msg = 'Token not valid'
raise exceptions.AuthenticationFailed(msg)
在覆盖中:
from rest_framework.views import exception_handler
def core_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
detail = []
for field, value in response.data.items():
if isinstance(value, list):
detail += value
else:
detail.append(value)
response.data['detail'] = ' '.join(detail)
if response.data['detail'] == 'Token not valid':
response.status_code = 401