Skip to content
This repository was archived by the owner on May 26, 2020. It is now read-only.

Commit 8b237bc

Browse files
committed
Allow subclassing JSONWebTokenAuthentication
1 parent 84f4157 commit 8b237bc

File tree

1 file changed

+40
-29
lines changed

1 file changed

+40
-29
lines changed

rest_framework_jwt/authentication.py

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,22 @@
1313
jwt_get_user_id_from_payload = api_settings.JWT_PAYLOAD_GET_USER_ID_HANDLER
1414

1515

16-
class JSONWebTokenAuthentication(BaseAuthentication):
16+
class JSONWebTokenAuthenticationBase(BaseAuthentication):
1717
"""
1818
Token based authentication using the JSON Web Token standard.
19-
20-
Clients should authenticate by passing the token key in the "Authorization"
21-
HTTP header, prepended with the string specified in the setting
22-
`JWT_AUTH_HEADER_PREFIX`. For example:
23-
24-
Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj
2519
"""
26-
www_authenticate_realm = 'api'
2720

2821
def authenticate(self, request):
2922
"""
3023
Returns a two-tuple of `User` and token if a valid signature has been
3124
supplied using JWT-based authentication. Otherwise returns `None`.
3225
"""
33-
auth = get_authorization_header(request).split()
34-
auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()
35-
36-
if not auth or smart_text(auth[0].lower()) != auth_header_prefix:
26+
jwt_value = self.get_jwt_value(request)
27+
if jwt_value is None:
3728
return None
3829

39-
if len(auth) == 1:
40-
msg = _('Invalid Authorization header. No credentials provided.')
41-
raise exceptions.AuthenticationFailed(msg)
42-
elif len(auth) > 2:
43-
msg = _('Invalid Authorization header. Credentials string '
44-
'should not contain spaces.')
45-
raise exceptions.AuthenticationFailed(msg)
46-
4730
try:
48-
payload = jwt_decode_handler(auth[1])
31+
payload = jwt_decode_handler(jwt_value)
4932
except jwt.ExpiredSignature:
5033
msg = _('Signature has expired.')
5134
raise exceptions.AuthenticationFailed(msg)
@@ -55,28 +38,56 @@ def authenticate(self, request):
5538

5639
user = self.authenticate_credentials(payload)
5740

58-
return (user, auth[1])
41+
return (user, jwt_value)
5942

6043
def authenticate_credentials(self, payload):
6144
"""
6245
Returns an active user that matches the payload's user id and email.
6346
"""
6447
User = utils.get_user_model()
6548

66-
try:
67-
user_id = jwt_get_user_id_from_payload(payload)
49+
user_id = jwt_get_user_id_from_payload(payload)
6850

69-
if user_id is not None:
51+
if user_id is not None:
52+
try:
7053
user = User.objects.get(pk=user_id, is_active=True)
71-
else:
72-
msg = _('Invalid payload.')
54+
except User.DoesNotExist:
55+
msg = _('Invalid signature.')
7356
raise exceptions.AuthenticationFailed(msg)
74-
except User.DoesNotExist:
75-
msg = _('Invalid signature.')
57+
else:
58+
msg = _('Invalid payload.')
7659
raise exceptions.AuthenticationFailed(msg)
7760

7861
return user
7962

63+
64+
class JSONWebTokenAuthentication(JSONWebTokenAuthenticationBase):
65+
"""
66+
Clients should authenticate by passing the token key in the "Authorization"
67+
HTTP header, prepended with the string specified in the setting
68+
`JWT_AUTH_HEADER_PREFIX`. For example:
69+
70+
Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj
71+
"""
72+
www_authenticate_realm = 'api'
73+
74+
def get_jwt_value(self, request):
75+
auth = get_authorization_header(request).split()
76+
auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()
77+
78+
if not auth or smart_text(auth[0].lower()) != auth_header_prefix:
79+
return None
80+
81+
if len(auth) == 1:
82+
msg = _('Invalid Authorization header. No credentials provided.')
83+
raise exceptions.AuthenticationFailed(msg)
84+
elif len(auth) > 2:
85+
msg = _('Invalid Authorization header. Credentials string '
86+
'should not contain spaces.')
87+
raise exceptions.AuthenticationFailed(msg)
88+
89+
return auth[1]
90+
8091
def authenticate_header(self, request):
8192
"""
8293
Return a string to be used as the value of the `WWW-Authenticate`

0 commit comments

Comments
 (0)