Flask应用中JWT存放在哪里可被jwt_required(optional=True)自动识别?
问题原因与修复方案
核心问题梳理
你现在的逻辑有3个关键错误导致JWT无法被正常识别:
- 登录API中你调用了
set_access_cookies等方法给resp对象设置cookie,但最终返回的是output字典而非resp对象,所有cookie设置完全未生效 - 你在重定向响应上添加
Authorization请求头是无效操作:你设置的是服务端返回给浏览器的响应头,浏览器发起首页跳转的新请求时不会携带该头信息 redirect(url_for('home.index'),access_token)写法错误:redirect第二个参数是HTTP状态码,你传入令牌属于语法错误,不会传递任何令牌信息
具体修复步骤
1. 清理登录API无效代码
登录API中如果仅返回JSON格式的令牌,删掉所有和cookie设置相关的无效代码:
# 删掉这几行,因为你没返回resp对象,设置了也没用 # resp = jsonify(login=True) # set_access_cookies(resp, access_token.encode('utf-8')) # set_refresh_cookies(resp, refresh_token.encode('utf-8')) # resp.set_cookie('X-CSRF-TOKEN-ACCESS', access_token.encode('utf-8')) # resp.set_cookie('X-CSRF-TOKEN-REFRESH', refresh_token.encode('utf-8'))
同时删掉调用登录API时多余的无效Authorization头:
# 删掉这行,此时还未生成令牌,写了也没用 # headers["Authorization"] = "Bearer {token}"
2. 修复登录后重定向逻辑
在user_login视图中,拿到令牌后将令牌设置到返回给浏览器的响应cookie中,浏览器后续请求会自动携带cookie,JWT扩展就能正常读取:
elif r.status_code==200: print("Login correct") flash("Log In successful") access_token = r.json()['access_token'] # 修复redirect写法,不要传多余的access_token参数 resp = redirect(url_for('home.index')) # 用JWT扩展提供的方法设置cookie,自动和配置匹配 set_access_cookies(resp, access_token) # 如果需要refresh令牌也可以同步设置 # set_refresh_cookies(resp, r.json()['refresh_token']) return resp
3. 确认JWT基础配置
确保你的Flask应用初始化时已经配置了JWT的cookie相关参数:
app.config["JWT_TOKEN_LOCATION"] = ["headers", "cookies"] # 开发环境关闭cookie安全校验,生产环境改回True app.config["JWT_COOKIE_SECURE"] = False # 如果不需要CSRF校验可以临时关闭方便测试 app.config["JWT_COOKIE_CSRF_PROTECT"] = False
为什么Postman测试正常
你在Postman中是手动将令牌添加到请求头后直接调用首页接口,符合JWT校验逻辑;而浏览器场景下你之前的代码没有将令牌正确传递给浏览器,导致跳转首页的请求没有携带任何令牌信息,因此校验失败。
内容的提问来源于stack exchange,提问作者JoelJoseph25
相关产品推荐
相关产品推荐

