Django + SimpleJWT: Токены доступа иногда истекают немедленно ("учетные данные не предоставлены") при вызове нескольких конечных точек

Я создаю интерфейс Vue 3 (развернутый на Vercel по адресу example.com) с использованием серверной части Django REST Framework (развернутой на Railway по адресу api.example.com).

Для аутентификации используются токены доступа/обновления JWT, хранящиеся в файлах cookie HttpOnly (доступ, обновление).

Срок службы токена доступа = 30 минут

Срок службы токена обновления = 1 день

Файлы cookie устанавливаются следующим образом: HttpOnly; Secure; SameSite=Нет; Domain=.example.com

Настройки часового пояса Django:

ЯЗЫКОВОЙ КОД = "en-us"

ВРЕМЕННАЯ ЗОНА = "Африка/Лагос"

USE_I18N = Истина

USE_TZ = Истина

Проблема

Когда интерфейс вызывает несколько конечных точек API одновременно (например, 5 запросов запускаются одновременно), некоторые из них выполняются успешно, а другие терпят неудачу:

401 Несанкционированный доступ

{"подробная информация":"Учетные данные для аутентификации не были предоставлены."}

В неудачных запросах я вижу, что файлы cookie отправлены:

файл cookie: доступ=...; обновление=...

Но SimpleJWT по-прежнему отклоняет токен доступа, иногда сразу после входа в систему.

Похоже, что утверждение exp в токене доступа уже осталось в прошлом, когда Django проверяет его.

Что я пробовал

Подтвержденные файлы cookie устанавливаются с правильным доменом и с параметрами: true.

Реализован перехватчик ответов Axios с повторной попыткой обновления токена.

Гарантированная проверка подлинности cookiejw проверяет как заголовок авторизации, так и файл cookie доступа.

Возможно, возникла какая-то проблема с конфигурацией. По истечении срока действия токена это сообщение не отображается Credentials not provided . Пожалуйста, убедитесь, что вы используете JWT authenticate, как показано ниже

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'ACCESS_TOKEN_LIFETIME': timedelta(hours=1),
}

Также обратите внимание: для аутентификации требуется только токен доступа в заголовках к ключу авторизации запроса, как показано ниже

Authorization: Bearer {access_token}

Когда токен истечет. Отображается сообщение, подобное приведенному ниже

{
  "detail": "Given token not valid for any token type",
  "code": "token_not_valid",
  "messages": [
    {
      "token_class": "AccessToken",
      "token_type": "access",
      "message": "Token is invalid or expired"
    }
  ]
}
Вернуться на верх