Ошибка истечения срока действия токена при использовании SimpleJWT TokenVeryifySerializer для возврата пользовательских данных

У меня есть бэкенд API приложение, которое использует DRF и SimpleJWT в качестве движка Auth.

Для фронт-энда React, использующего auth API, требуется конечная точка, которая будет принимать токен доступа, проверять его и возвращать объект токена и связанный с ним объект пользователя.

Я хочу расширить существующий в SimpleJWT TokenVerifySerializer, чтобы сделать это, поскольку он уже содержит логику проверки и черного списка.

Я упираюсь в стену, когда пытаюсь это сделать, так как продолжаю получать Token is invalid or expired error даже если токен действителен

Любые указания на то, где может быть проблема, будут очень признательны!

Код следующий:

# apiauth/serializer.py

from django.contrib.auth.models import User
from django.apps import apps
from django.contrib.auth.password_validation import validate_password
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenVerifySerializer
from rest_framework_simplejwt.settings import api_settings
from rest_framework_simplejwt.tokens import RefreshToken, SlidingToken, UntypedToken, AccessToken

if api_settings.BLACKLIST_AFTER_ROTATION:
    from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['username'] = user.username
        token['email'] = user.email
        return token

class TokenUserSerializer(TokenVerifySerializer):
    token = serializers.CharField()

    def validate(self, attrs):

        access_token = UntypedToken(attrs["token"])

        if (
            api_settings.BLACKLIST_AFTER_ROTATION
            and apps.is_installed("rest_framework_simplejwt.token_blacklist")
        ):
            jti = access_token.get(api_settings.JTI_CLAIM)
            if BlacklistedToken.objects.filter(token__jti=jti).exists():
                raise ValidationError("Token is blacklisted")

        token = AccessToken(access_token)
        user = User.objects.get(access_token['user_id'])

        return {user}

class RegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(
        write_only=True, required=True, validators=[validate_password])
    password2 = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = User
        fields = ('username', 'password', 'password2')

    def validate(self, attrs):
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError(
                {"password": "Password fields didn't match."})

        return attrs

    def create(self, validated_data):
        user = User.objects.create(
            username=validated_data['username']
        )

        user.set_password(validated_data['password'])
        user.save()

        return user
# apiauth/views.py

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.http import JsonResponse
from apiauth.serializer import MyTokenObtainPairSerializer, TokenUserSerializer, RegisterSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.views import TokenVerifyView
from rest_framework import generics
from django.contrib.auth.models import User
from rest_framework.permissions import AllowAny, IsAuthenticated

# Create your views here.

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

class TokenUserView(TokenVerifyView):
    serializer_class = TokenUserSerializer

class RegisterView(generics.CreateAPIView):
    queryset = User.objects.all() 
    permission_classes = (AllowAny,)
    serializer_class = RegisterSerializer

@api_view(['GET'])
def getRoutes(request):
    routes = [
        '/apiauth/token/',
        '/apiauth/token/user/',
        '/apiauth/register/',
        '/apiauth/token/refresh/'
    ]
    return Response(routes)
# urls.py
from django.contrib import admin
from django.urls import path, re_path, include
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from jobs import views as jobs_views
from items import views as items_views
from contacts import views as contacts_views

schema_view = get_schema_view(
   openapi.Info(
      title="Basterfield Conductor API",
      default_version='v1',
      description="Basterfield Conductor API",
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
    re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
    path('apiauth/', include("apiauth.urls")),
    path('jobs/', jobs_views.jobs_list),
    path('jobs/<int:job_id>/', jobs_views.jobs_detail),
    path('items/', items_views.items_list),
    path('items/<int:item_id>/', items_views.items_detail),
    path('contacts/', contacts_views.contacts_list),
    path('contacts/<int:contact_id>/', contacts_views.contacts_detail),
]
Вернуться на верх