Django restframework-simple-jwt: Не удалось десериализовать данные ключа
Я пытаюсь использовать django-simplejwt & restframework с RSA256. Я сгенерировал свою пару ключей, следуя this gist. Открытая и закрытая пары ключей сохраняются в файле .env:
JWT_SIGNING_KEY='-----BEGIN RSA PRIVATE KEY-----\\n
keydata\\n
-----END RSA PRIVATE KEY-----'
JWT_VERIFYING_KEY='-----BEGIN PUBLIC KEY-----\\n
keydata\\n
-----END PUBLIC KEY-----'
Мой jwt configuration settings.py выглядит следующим образом (дополнительная информация для совместимости с Auth0):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
SIGNING_KEY = os.getenv("JWT_SIGNING_KEY")
VERIFYING_KEY = os.getenv("VERIFYING_KEY")
SIMPLE_JWT = {
'USER_ID_FIELD': 'user_id',
'ACCESS_TOKEN_LIFETIME': timezone.timedelta(minutes=10),
'REFRESH_TOKEN_LIFETIME': timezone.timedelta(hours=6),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM' : 'RS256', # Default would be HS256
'SIGNING_KEY' : f'''{SIGNING_KEY}''', #config("JWT_SIGNING_KEY"), # Must be private key
'VERIFYING_KEY' : f'''{VERIFYING_KEY}''', #config("JWT_VERIFYING_KEY"), # Must be public key
'AUDIENCE' : config("JWT_AUDIENCE"),
'ISSUER': config("JWT_ISSUER"),
'JWK_URL': f'{config("JWT_ISSUER")}/.well-known/jwks.json',
'USER_ID_CLAIM': f'{config("JWT_AUDIENCE")}/email',
'JTI_CLAIM': None,
'TOKEN_TYPE_CLAIM': None,
'AUTH_HEADER_TYPES': ('Bearer',),
}
При вызове ограниченных представлений, которым необходим объект пользователя, выполняется функция декодирования jwt-токена и возврата соответствующего объекта пользователя:
def token_user(request):
s, token = request.META["HTTP_AUTHORIZATION"].split(" ")
decoded = jwt.decode(token, settings.VERIFYING_KEY, algorithms=["RSA256"])
username = decoded["username"]
user = get_user_model().objects.filter(username=username)
return user
Вот мой Login view & LoginSerializer (я вырезал большую часть процесса валидации, так как это работало до внедрения jwt. Я оставил часть, генерирующую токен):
#views.py
class Login(TokenObtainPairView):
serializer_class = LoginSerializer
#serializers.py
class LoginSerializer(TokenObtainPairSerializer):
username_field = get_user_model().USERNAME_FIELD
password = serializers.CharField(write_only=True, required=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[self.username_field] = serializers.CharField()
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['username'] = user.username
return token
def validate(self, attrs):
....
refresh = self.get_token(user)
attrs["refresh"] = str(refresh)
attrs["access"] = str(refresh.access_token)
....
При попытке входа в систему я получаю следующую ошибку:
ValueError: ('Не удалось десериализовать данные ключа. Данные могут быть в неправильном формате, они могут быть зашифрованы неподдерживаемым алгоритмом, или это может быть неподдерживаемый тип ключа (например, кривые EC с явными параметрами).', [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
>