Как правильно решить ошибку с RefreshToken?
Не проходит авторизация через simple-jwt, я создал свою кастомную апку в которой делаю кастомную регистрацию и авторизация
Вот код контроллера:"
from django.contrib.auth import authenticate from rest_framework import views, status from rest_framework.response import Response from rest_framework_simplejwt.exceptions import TokenError from rest_framework_simplejwt.tokens import Token from .serializers import UserSerializer class LoginView(views.APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: try: token = Token.for_user(user) return Response({ 'access': str(token.access_token), 'refresh': str(token) }) except TokenError as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED) class RegisterView(views.APIView): def post(self, request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response({'message': 'User created successfully'}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
from django.contrib.auth import authenticate from rest_framework import views, status from rest_framework.response import Response from rest_framework_simplejwt.exceptions import TokenError from rest_framework_simplejwt.tokens import Token from .serializers import UserSerializer class LoginView(views.APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: try: token = Token.for_user(user) return Response({ 'access': str(token.access_token), 'refresh': str(token) }) except TokenError as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED) class RegisterView(views.APIView): def post(self, request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response({'message': 'User created successfully'}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
но при запросе на *host*/api/login/ и отправки json объекта с данными авторизации получаю:
{ "error": "Невозможно создать токен без типа или времени жизни" } |
{ "error": "Невозможно создать токен без типа или времени жизни" }
В настройках проекта, все стоит как в документации у jwt и время жизни определенно для двух токенов
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ] } SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5), "REFRESH_TOKEN_LIFETIME": timedelta(days=1), "ROTATE_REFRESH_TOKENS": False, "BLACKLIST_AFTER_ROTATION": False, "UPDATE_LAST_LOGIN": False, "ALGORITHM": "HS256", "SIGNING_KEY": SECRET_KEY, "VERIFYING_KEY": "", "AUDIENCE": None, "ISSUER": None, "JSON_ENCODER": None, "JWK_URL": None, "LEEWAY": 0, "AUTH_HEADER_TYPES": ("Bearer",), "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "TOKEN_TYPE_CLAIM": "token_type", "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser", "JTI_CLAIM": "jti", "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp", "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5), "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1), "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer", "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer", "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", } |
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ] } SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5), "REFRESH_TOKEN_LIFETIME": timedelta(days=1), "ROTATE_REFRESH_TOKENS": False, "BLACKLIST_AFTER_ROTATION": False, "UPDATE_LAST_LOGIN": False, "ALGORITHM": "HS256", "SIGNING_KEY": SECRET_KEY, "VERIFYING_KEY": "", "AUDIENCE": None, "ISSUER": None, "JSON_ENCODER": None, "JWK_URL": None, "LEEWAY": 0, "AUTH_HEADER_TYPES": ("Bearer",), "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "TOKEN_TYPE_CLAIM": "token_type", "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser", "JTI_CLAIM": "jti", "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp", "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5), "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1), "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer", "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer", "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", }
Пытался вместо "from rest_framework_simplejwt.tokens import Token" использовать refrash но попадал на ошибку что рефреш токен не имеет атрибута setter
Пожалуйста помогите разобраться в данной теме !
Дополнительно:
а чем тебя TokenObtainPairView не устроил? зачем свой view писать? ну и раз захотел писать свой, наверно лучше и наследовать от TokenObtainPairView надо было?
ну и не нужно все значения по умолчанию копипастить в SIMPLE_JWT, достаточно тех которые они них отличаются
from django.contrib.auth import authenticate from rest_framework import views, status from rest_framework.response import Response from rest_framework_simplejwt.exceptions import TokenError from rest_framework_simplejwt.tokens import Token from .serializers import UserSerializer from rest_framework_simplejwt.views import TokenObtainPairView class LoginView(TokenObtainPairView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: try: token = Token.for_user(user) return Response({ 'access': str(token.access_token), 'refresh': str(token) }) except TokenError as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED) |
from django.contrib.auth import authenticate from rest_framework import views, status from rest_framework.response import Response from rest_framework_simplejwt.exceptions import TokenError from rest_framework_simplejwt.tokens import Token from .serializers import UserSerializer from rest_framework_simplejwt.views import TokenObtainPairView class LoginView(TokenObtainPairView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(username=username, password=password) if user: try: token = Token.for_user(user) return Response({ 'access': str(token.access_token), 'refresh': str(token) }) except TokenError as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)
отредактировал класс и не чего не помогло, по прежнему ошибка времени жизни, потребовалось для обучения, и столкнулся с такой ошибкой
по поводу что не все константы нужны в курсе сейчас просто хочу понять причину моей ошибки
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для правильного решения проблемы с RefreshToken необходимо следовать определенным шагам. Во-первых, удостоверьтесь, что вы правильно настроили механизм RefreshToken в вашем приложении.
Для начала, убедитесь, что RefreshToken был корректно создан и сохранен в базе данных. Проверьте, что RefreshToken соответствует пользователю, для которого он был создан, и что он не истек.
Затем, убедитесь, что ваш сервер правильно обрабатывает запрос на обновление токена. Проверьте, что ваше приложение корректно проверяет валидность RefreshToken и выдает новый AccessToken при успешном обновлении.
Если вы получаете ошибку с RefreshToken, то рекомендуется добавить логирование в вашем приложении, чтобы вы могли отследить, в каком месте происходит ошибка. Посмотрите на сообщение об ошибке, возможно оно даст вам подсказку о причине проблемы.
Также, убедитесь, что ваше приложение правильно обрабатывает исключения, связанные с RefreshToken. Например, если RefreshToken истек или недействителен, ваше приложение должно корректно обработать эту ситуацию и вернуть соответствующее сообщение об ошибке.
Не забывайте также о безопасности. Убедитесь, что ваш механизм обновления токена защищен от атак, таких как перехват RefreshToken или подбор его другими пользователями. Используйте HTTPS для передачи токенов и храните RefreshToken в безопасном месте.
Надеюсь, эти рекомендации помогут вам правильно решить проблему с RefreshToken в вашем приложении. Если у вас остались дополнительные вопросы, не стесняйтесь задавать их для получения более подробной помощи.