不能只用create_access_token和create_refresh_token直接返回,因未显式配置过期时间会导致refresh token沿用access token的15分钟有效期,且fresh属性缺失会使@jwt_required(fresh=true)失效,同时需配合set_access_cookies/set_refresh_cookies写入响应或统一配置jwt_token_location传输方式。

为什么不能只用 create_access_token 和 create_refresh_token 直接返回?
直接调用这两个函数生成 token 后返回,看似完成了双 Token 流程,但实际漏掉了关键约束:Flask-JWT-Extended 默认不会自动为 refresh token 设置 fresh 属性,也不会阻止非 fresh 的 access token 调用需高权限的接口。更严重的是,如果没显式配置 JWT_REFRESH_TOKEN_EXPIRES,refresh token 会沿用 access token 的过期时间(默认 15 分钟),导致刷新功能形同虚设。
实操建议:
- 必须在
create_refresh_token之外,额外调用set_access_cookies和set_refresh_cookies写入响应头或 Cookie,不能只靠jsonify返回原始字符串 - 在
app.config中明确设置JWT_ACCESS_TOKEN_EXPIRES = 15 * 60和JWT_REFRESH_TOKEN_EXPIRES = 7 * 24 * 3600(7 天) - 若使用 Cookie 模式,务必开启
JWT_COOKIE_SECURE = True(生产环境)和JWT_COOKIE_SAMESITE = 'Lax'防 CSRF
如何让 @jwt_required(fresh=True) 真正生效?
这个装饰器不是“自动识别 fresh”,而是依赖 access token payload 中是否存在 "fresh": True 字段,且该字段必须由 create_access_token(fresh=True) 显式写入。普通登录返回的 access token 默认是 fresh=False,即使它刚生成也不满足条件。
常见错误现象:@jwt_required(fresh=True) 接口始终返回 401,即使 token 有效、未过期。
实操建议:
- 登录接口中,仅对首次登录(如密码校验成功)调用
create_access_token(identity=user, fresh=True) - 刷新接口(
/refresh)中,只能用create_access_token(identity=get_jwt_identity(), fresh=False)—— 刷新出来的 access token 必须是非 fresh 的,否则就绕过了 fresh 机制的设计本意 - 检查 token 内容可用
get_jwt(),确认返回字典里有"fresh": True/False
刷新接口为何总报 RuntimeError: No refresh token present?
这个错误不单指请求没带 refresh token,更常因 Cookie 名称或传输方式不匹配触发。Flask-JWT-Extended 默认从 Cookie 读取名为 refresh_token_cookie 的值;若你手动用 Header(如 Authorization: Bearer xxx)传 refresh token,框架根本不会去解析它。
使用场景:前后端分离项目常用 Axios,默认不发送 Cookie,此时必须切换为 Header 模式,但需同步改配置。
实操建议:
- 统一传输方式:要么全 Cookie(配
JWT_TOKEN_LOCATION = ['cookies']),要么全 Header(配JWT_TOKEN_LOCATION = ['headers']) - 若选 Header 模式,刷新接口必须从
AuthorizationHeader 解析 refresh token,需自定义@jwt.token_in_blocklist_loader和手动调用verify_jwt_in_request(locations=['headers']) - Cookie 模式下,确保前端请求携带
credentials: 'include',且后端响应头含Access-Control-Allow-Credentials: true
access token 和 refresh token 存储位置冲突怎么办?
当同时启用 Cookie 和 Header 双模式(JWT_TOKEN_LOCATION = ['cookies', 'headers']),框架会按顺序查找:先找 Cookie 里的 access_token_cookie,再找 Header 里的 Authorization。一旦 Cookie 存在但已过期,就不会 fallback 到 Header,导致误判。
性能与兼容性影响:混合模式增加解析开销,且在跨域调试时极易因 Cookie 未携带或 SameSite 限制失败。
实操建议:
- 生产环境坚持单一模式:Web 应用优先 Cookie(防 XSS 需配合
HttpOnly),纯 API 或移动端用 Header - Cookie 模式下,两个 token 必须用不同 Cookie 名:通过
JWT_ACCESS_COOKIE_NAME = 'access_token'和JWT_REFRESH_COOKIE_NAME = 'refresh_token'显式区分 - 不要试图用同一个 Cookie 字段存两个 token,框架不支持,也无法解耦过期逻辑
双 Token 认证的复杂点不在生成,而在 token 生命周期的严格分治:access token 要短、可废止、fresh 属性可控;refresh token 要长、只用于换新 access token、绝不参与业务鉴权。任何一步混用或配置错位,都会让安全模型失效。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











