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"
}
]
}