mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 08:29:59 +03:00
Add machine-readable status to Authentication classes
BasicAuthentication and TokenAuthentication have two failure cases when they are passed technically valid credentials by an API client: - the passed credentials are not correct - the credentials are correct but the user is inactive In both cases, only a human-readable 'detail' is returned in the 401 body, which is translated according to the site settings: ```json HTTP/1.1 401 Unauthorized <headers snipped> { "detail": "Ungültiges Token" } ``` The free-form text and its translation make it impossible for an API consumer to determine the actual reason (inactive user, out of luck; or wrong credentials, try again). This PR adds a machine-readable 'status' field to the response, which can take one of two values: 1. `invalid-credentials` - returned when the passed username, password or token were incorrect. 2. `inactive-user` - returned when the credentials were valid but the user account is disabled. Example: ```json HTTP/1.1 401 Unauthorized <headers snipped> { "detail": "Ungültiges Token", "status": "invalid-token" } ``` As this only adds a machine-readable field for the already exposed human-readable 'detail' field, there are no new security implications.
This commit is contained in:
parent
b1004a4733
commit
cfd9a7e90a
|
@ -98,10 +98,10 @@ class BasicAuthentication(BaseAuthentication):
|
||||||
user = authenticate(request=request, **credentials)
|
user = authenticate(request=request, **credentials)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise exceptions.AuthenticationFailed(_('Invalid username/password.'))
|
raise exceptions.AuthenticationFailed({'detail': _('Invalid username/password.'), 'status':'invalid-credentials'})
|
||||||
|
|
||||||
if not user.is_active:
|
if not user.is_active:
|
||||||
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
|
raise exceptions.AuthenticationFailed({'detail': _('User inactive or deleted.'), 'status':'inactive-user'})
|
||||||
|
|
||||||
return (user, None)
|
return (user, None)
|
||||||
|
|
||||||
|
@ -200,10 +200,10 @@ class TokenAuthentication(BaseAuthentication):
|
||||||
try:
|
try:
|
||||||
token = model.objects.select_related('user').get(key=key)
|
token = model.objects.select_related('user').get(key=key)
|
||||||
except model.DoesNotExist:
|
except model.DoesNotExist:
|
||||||
raise exceptions.AuthenticationFailed(_('Invalid token.'))
|
raise exceptions.AuthenticationFailed({'detail': _('Invalid token.'), 'status':'invalid-credentials'})
|
||||||
|
|
||||||
if not token.user.is_active:
|
if not token.user.is_active:
|
||||||
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
|
raise exceptions.AuthenticationFailed({'detail': _('User inactive or deleted.'), 'status':'inactive-user'})
|
||||||
|
|
||||||
return (token.user, token)
|
return (token.user, token)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user