Flask-JWT-Extended:已设Cookie但@jwt_required()仍返回未授权
我在Flask后端使用Flask-JWT-Extended处理身份认证,将JWT令牌存储在HttpOnly Cookie中。登录流程成功在浏览器中设置了access_token_cookie,且可在Chrome开发者工具的Application→Cookies中查看,但向受@jwt_required()装饰器保护的接口发起请求时,收到401未授权错误,令牌未在请求中携带。
后端(Flask)代码
@shop_bp.route("/signin", methods=['POST']) def shop_login(): try: data = request.json shop = Shop.query.filter_by(shop_phone=data['shop_number']).first() if shop and shop.password == data['password']: access_token = create_access_token(identity=f'shop:{shop.id}') response = make_response(jsonify({"message": True})) set_access_cookies(response, access_token) return response return jsonify({'message': False}), 401 except Exception as e: print("Error in ShopSignIn:", str(e)) print(traceback.format_exc()) return jsonify({"error": "Internal Server Error"}), 500
前端请求(Vue.js + Axios)代码
actions: { async checkAuthStatus() { try { const response = await axios.get('http://127.0.0.1:5000/auth/check_login_status', { withCredentials: true, headers: { "Content-Type": "application/json" } }); this.isShopLoggedIn = true; if (response.data.logged_in) { return this.userId; } else { this.resetAuthState(); } } catch (error) { console.error('Auth check failed:', error); this.resetAuthState(); } }, }
已尝试的解决措施
- 验证浏览器中已设置Cookie
- 确保Axios请求中包含
withCredentials: true - 将
JWT_COOKIE_SAMESITE从"Strict"改为"Lax" - 在Flask中设置
CORS(supports_credentials=True) - 检查响应中是否存在冲突的set-cookie头
解决方案
1. 明确配置Flask-JWT-Extended从Cookie读取令牌
默认情况下Flask-JWT-Extended可能只从请求头读取令牌,需要显式配置让它从Cookie获取:
app.config['JWT_TOKEN_LOCATION'] = ['cookies']
2. 配置Cookie的Domain和Path
如果前端和后端运行在不同端口(比如前端8080、后端5000),需要指定Cookie的Domain和Path,确保浏览器能正确携带:
app.config['JWT_COOKIE_DOMAIN'] = '127.0.0.1' app.config['JWT_COOKIE_PATH'] = '/' # 本地开发非HTTPS环境下关闭Secure属性 app.config['JWT_COOKIE_SECURE'] = False
3. 修正CORS配置
带withCredentials的请求不能用通配符*作为origins,需要指定前端的具体地址:
from flask_cors import CORS CORS(app, origins="http://localhost:8080", supports_credentials=True)
4. 调试请求中的Cookie
在受保护的接口中添加调试代码,确认请求是否携带了Cookie:
@shop_bp.route("/auth/check_login_status") @jwt_required() def check_login_status(): print("Request Cookies:", request.cookies) # 查看是否有access_token_cookie identity = get_jwt_identity() return jsonify(logged_in=True, identity=identity)
5. 检查令牌的有效期和签名
确保生成的access_token有效期足够(默认15分钟),并且Flask-JWT-Extended的JWT_SECRET_KEY配置正确,签名不匹配也会导致令牌无法识别。
内容的提问来源于stack exchange,提问作者Hem
相关产品推荐
相关产品推荐

