You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Simple JWT 间歇性Token无效/过期报错问题求助

Django Simple-JWT 随机验证失败问题

搭建基于Simple-JWT的Django REST后端,部署到AWS Lightsail服务器后出现异常:约2/3的请求返回token无效错误,剩余请求可正常响应。同一access token连续发起两次请求,可能第一次失败、第二次成功。本地运行完全正常,服务器仅配置了Cloudflare和Nginx。

错误示例

失败请求返回:

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

连续两次curl请求示例:

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 配置

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;
    }
}

可能的问题原因

  • 服务器时间不同步:AWS Lightsail实例可能存在时间偏差,JWT验证依赖精确时间对比,若服务器时间与token签发时间差超过配置的LEEWAY(60秒),会触发验证失败。本地时间正常但服务器时间不稳定,会导致随机失败。
  • 多进程/实例密钥不一致:如果后端用多进程部署(如gunicorn多worker)或多实例,需确保所有进程/实例的SECRET_KEY完全一致。若密钥不统一,部分进程能正确验证token,部分不能,就会出现随机失败。
  • Cloudflare 请求头改写或丢失:Cloudflare的缓存规则或安全策略可能在部分请求中改写、丢失Authorization头,导致后端无法获取有效token。需检查Cloudflare对API路径的缓存设置,确保请求头完整传递。
  • Nginx 请求头传递问题:当前Nginx配置未显式指定传递Authorization头,可能在某些场景下丢失该头。可尝试添加proxy_pass_header Authorization;到location /块中,确保token头正确转发到后端。
  • Token黑名单存储不稳定:配置了BLACKLIST_AFTER_ROTATION,若黑名单存储(如Redis)存在连接波动,部分请求无法查询token黑名单状态,导致误判token无效。可临时关闭黑名单功能测试是否解决问题。
  • 网络波动导致请求截断:AWS或Cloudflare的网络波动可能导致Authorization头在传输中被截断,部分请求的token不完整,触发验证失败。可在后端日志中记录收到的Authorization头内容,检查是否存在不完整的情况。

内容的提问来源于stack exchange,提问作者Dakopen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:44:58