Первый вызов django rest api возвращает request.user как AnonymousUser, но последующие вызовы возвращают правильного пользователя

Прямо сейчас у меня есть представление api, которое требует знать, какой пользователь в настоящее время вошел в систему. Когда я пытаюсь вызвать его с зарегистрированным пользователем, однако, он возвращает анонимного пользователя. Странно то, что если я вызываю api представление снова, оно возвращает правильного пользователя. Я использую django rest framework и JSON Web Tokens с помощью simplejwt. Сейчас вызов в ReactJS выглядит следующим образом:

const fetchAuthorData = () => {
        axiosInstance.get('authors/')
        .then((res) => {
            setAuthor(res.data)
        }).catch((err) => {
            fetchAuthorData()
        })
        
        fetchAuthorThreads()
        fetchAuthorArticles()
    }

Однако я знаю, что рекурсивное обращение к этому снова и снова очень опасно, потому что даже если я перенаправляю, если пользователь действительно не вошел в систему до этого рекурсивного вызова api, если каким-то образом это не удастся, мой сервер будет перегружен вызовами api. Кто-нибудь знает, как я могу сделать так, чтобы мой api действительно правильно определял при первом вызове, вошел ли пользователь в систему?

Вот ошибочное мнение:

@api_view(['GET'])
def author(request):
    print(request.user)
    if request.user.is_authenticated:
        author = request.user
        serializer = AuthorAccessSerializer(author, many=False)
        return Response(serializer.data)
    else:
        return HttpResponse(status=400)

В этом случае request.user является анонимным пользователем, хотя я вошел в систему

Вот аналогичная часть другого представления, которая работает странно

@api_view(['GET', 'POST'])
def articles(request):
    if request.method == 'GET':
        category_name = request.query_params['category']
        dash = request.query_params['dash']
        #this part is very similiar and works for some reason
        if dash == "True":
            if request.user.is_authenticated:
                articles = Article.objects.filter(author=request.user)
            else:
                return HttpResponse(status=401)
        # *end part*
        elif category_name:
            try:
                category = Category.objects.get(name__icontains=category_name)
            except:
                return HttpResponse(status=400, content="Category not found")
            articles = Article.objects.filter(category=category)
        else:
            articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        
        return Response(serializer.data)

Вот мои настройки axios:

export const axiosInstance = axios.create({
    baseURL: baseURL,
    timeout: 5000,
    headers : {
        Authorization: localStorage.getItem('access_token')
            ? 'JWT' + localStorage.getItem('access_token')
            : null,
        'Content-Type' : 'application/json',
        accept : 'application/json'
    }
})

А вот мои настройки rest framework и JWT auth:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(hours=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer', 'JWT'),
    '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',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

ALLOWED_HOSTS=['127.0.0.1', 'http://localhost:5000']
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000',
) 

Опять же, если я продолжаю вызывать тот же api вызов, он почему-то работает, не изменяя никаких заголовков авторизации, токенов или чего-либо еще, и request.user работает нормально со вторым представлением, которое у меня есть выше. Может ли кто-нибудь сказать мне, почему это происходит?

Я думаю,

                1. localStorage.setItem('access_token', response.data.access)
                2. localStorage.setItem('refresh_token', response.data.refresh)
                3. axiosInstance.defaults.headers['Authorization'] = 
                    'JWT ' + localStorage.getItem('access_token')
                    history.push('/')

код входа в систему может вызвать проблему.

Этот код никогда не выполняется последовательно; каждый javascript выполняется асинхронно.

Значит, ваш axiosInstance.defaults.headers может быть нулевым, потому что 1, 2 и 3 строки выполняются одновременно. Другими словами, axiosInstance.defaults.headers становится нулевым (так как нет access_token на localStorage), тогда, Js устанавливает access_token из response.data.access.

Вам лучше использовать обещание с .then() после 1 и 2 строки, или получить авторизацию axiosInstance при выполнении http запроса.

Вернуться на верх