I am migrating our Django code that uses djangorestframework-jwt
to the latest version of djangorestframework-simplejwt
(5.2.2) in Django 4.0.8. I am having an issue while trying to verify the token.
The issue is because of the fact that our pem file for retrieving public and private keys is hosted on an Amazon S3 bucket. The framework requires passing SIGNING_KEY
and VERIFYING_KEY
statically or using JWK_URL
for dynamically injecting these keys. Is there a way to provide these keys dynamically without using JWK_URL
?
The djangorestframework-jwt
framework used to provide handlers for decoding (JWT_DECODE_HANDLER
) and encoding (JWT_ENCODE_HANDLER
) the JWT payload. The djangorestframework-simplejwt
has built-in functions to decode/encode inside the TokenBackend
class. I also see that TOKEN_BACKEND_CLASS
is part of REMOVED_SETTINGS
in api_settings
. I am having difficulty trying to write a custom backend by overriding decode()
and encode()
functions. How can I accomplish this?
You can achieve this by overriding your serializer in the following fashion.
from rest_framework_simplejwt.serializers import TokenVerifySerializer
from rest_framework_simplejwt.exceptions import (
InvalidToken,
AuthenticationFailed,
TokenBackendError,
TokenError
)
class MyTokenVerifySerializer(TokenVerifySerializer):
"""
Check the veracity of an access token.
"""
def validate(self, attrs):
token = attrs['token']
payload = {}
# Decode Token
try:
payload = jwt_decode_handler(token) # Your Decode handler
except TokenBackendError:
raise TokenError(_("Token is invalid or expired"))
user = self.get_user(payload=payload)
return {'token': token, 'user': user}
def get_user(self, payload):
"""
Attempts to find and return a user using the given validated token.
"""
from rest_framework_simplejwt.settings import api_settings
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _
try:
user_id = payload[api_settings.USER_ID_CLAIM]
except KeyError:
raise InvalidToken(_("Token contained no recognizable user identification"))
user_model = get_user_model()
try:
user = user_model.objects.get(**{api_settings.USER_ID_FIELD: user_id})
except self.user_model.DoesNotExist:
raise AuthenticationFailed(_("User not found"), code="user_not_found")
if not user.is_active:
raise AuthenticationFailed(_("User is inactive"), code="user_inactive")
return user
Hope this helps! Cheers