Простой JWT иногда говорит "Token is invalid or expired", а иногда выдает правильный результат
У меня есть бэкенд Django REST, настроенный на решение Simple-JWT. Примерно 2/3 запросов возвращают #
{"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"}]}
, а остальные возвращают нормальный результат. Например, эти скрутки я выполнял непосредственно друг за другом, и первая не сработала, а вторая (с тем же маркером доступа) вернула правильное значение:
C:\Users\user>curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzE4NDAxMzc5LCJpYXQiOjE3MTg0MDA0NzksImp0aSI6Ijc2YTcwZjU0OTA2ZjQwOTNhYzc2MzRhYTFmNmJjNTlhIiwidXNlcl9pZCI6Miwicm9sZSI6MSwibGFuZ3VhZ2UiOm51bGwsImZ1bGxfYWNjZXNzX2dyb3VwIjp0cnVlfQ.p8BRy95SSiBmqeSjmCkAHFddRjKmzEOowP2RT34Jp6Y" http://3.71.19.16/accounts/courses/
{"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"}]}
C:\Users\user>curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzE4NDAxMzc5LCJpYXQiOjE3MTg0MDA0NzksImp0aSI6Ijc2YTcwZjU0OTA2ZjQwOTNhYzc2MzRhYTFmNmJjNTlhIiwidXNlcl9pZCI6Miwicm9sZSI6MSwibGFuZ3VhZ2UiOm51bGwsImZ1bGxfYWNjZXNzX2dyb3VwIjp0cnVlfQ.p8BRy95SSiBmqeSjmCkAHFddRjKmzEOowP2RT34Jp6Y" http://3.71.19.16/accounts/courses/
[{"id":1,"name":"Testkurs 1","language":1,"teacher":2,"grade":5,"start_date":null,"study_started":false,"activate_final_test":false,"number_of_students":90,"created_at":"2024-06-11T14:13:15.498484Z","scheduled_study_start":null,"scheduled_final_test":null,"demo":false},{"id":2,"name":"Testkurs 2","language":1,"teacher":2,"grade":5,"start_date":null,"study_started":false,"activate_final_test":false,"number_of_students":70,"created_at":"2024-06-11T14:17:58.503959Z","scheduled_study_start":null,"scheduled_final_test":null,"demo":false},{"id":3,"name":"Test","language":1,"teacher":2,"grade":5,"start_date":null,"study_started":false,"activate_final_test":false,"number_of_students":0,"created_at":"2024-06-13T22:35:51.513376Z","scheduled_study_start":null,"scheduled_final_test":null,"demo":false}]
Вот моя Django Simple JWT-Setup:
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=15),
"REFRESH_TOKEN_LIFETIME": timedelta(days=90),
"ROTATE_REFRESH_TOKENS": True,
"BLACKLIST_AFTER_ROTATION": True,
"UPDATE_LAST_LOGIN": False,
"ALGORITHM": "HS256",
"VERIFYING_KEY": "",
"AUDIENCE": None,
"ISSUER": None,
"JSON_ENCODER": None,
"JWK_URL": None,
"LEEWAY": 60,
"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=15),
"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",
}
и мой конфиг nginx
server {
listen 80;
server_name 127.0.0.1; # change with url
location = /favicon.ico {
access_log off;
log_not_found off;
}
location /static/ {
alias /home/ubuntu/USER/static/;
}
location / {
# Add the necessary headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8000;
}
}
Он отлично работает, когда я запускаю сервер на localhost на своем домашнем компьютере, но имеет проблемы на машине AWS lightsail с почти такой же настройкой. На машине установлены только Cloudflare и Nginx.
Кто-нибудь знает, в чем может быть проблема? Я пытаюсь исправить это уже почти 8 часов...
Я только что нашел решение. Процент правильных ответов в 1/3 помог мне понять, что я также использую gunicorn с ровно 3 рабочими. Я понял, что использую функцию Django get_random_secret_key
, которая генерирует случайный ключ для каждого работника gunicorn, и поэтому они часто НЕ совпадают.