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

Flask-JWT-Extended:已设Cookie但@jwt_required()仍返回未授权

Flask-JWT-Extended的HttpOnly Cookie未随请求携带,导致@jwt_required()返回401

我在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:57:36