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

Flask-JWT-Extended配置:让Refresh Cookie适配直连与代理请求

环境信息

  • 后端:Flask 通过 flask run 运行在 5000 端口
  • 前端:React 应用运行在 3000 端口,使用 http-proxy-middleware 做代理
  • Cookie 配置:
JWT_REFRESH_COOKIE_PATH = "/refresh"

该配置确保仅向 /refresh 请求发送 Refresh Cookie,且 Cookie 带有 httponly 属性。

问题描述

  • 直连 Flask 接口(http://localhost:5000/refresh):通过 Postman 或 flask-restx 自动生成的 Swagger 文档访问均正常,Cookie 能正确携带。
  • React 代理访问:前端发起 http://localhost:3000/api/refresh 请求,经代理转发到 Flask 的 /refresh,但浏览器识别请求路径为 /api/refresh,不会发送 Path 为 /refresh 的 Refresh Cookie。

代理配置(setupProxy.js)

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:5000',
      changeOrigin: true,
    })
  );
};

需求

Refresh Cookie 仅在请求 /refresh 相关路径时发送,同时支持两种场景:

  1. 直接向 Flask 发起 http://localhost:5000/refresh 请求
  2. 从 React 应用发起 http://localhost:3000/api/refresh 请求,经代理转发到 Flask 的 /refresh

已尝试方案

  • 动态设置 Cookie 路径:请求到达 Flask 时路径均为 /refresh,无法区分是否来自代理
  • 修改 JWT_REFRESH_COOKIE_PATH 为 "/api/refresh":仅 React 场景正常,Swagger 直连场景失效
  • 修改代理匹配所有路径:导致 React 应用被重定向到 Flask 的 5000 端口,前端无法正常运行

解决方案

利用 http-proxy-middleware 的钩子,在代理响应返回前端时动态修改 Cookie 的 Path 属性,同时在请求转发时处理路径映射。

修改后的 setupProxy.js:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:5000',
      changeOrigin: true,
      // 转发时将 /api/refresh 重写为 /refresh
      pathRewrite: {
        '^/api/refresh': '/refresh'
      },
      // 响应返回前端时,将 Cookie 的 Path 从 /refresh 改为 /api/refresh
      onProxyRes: function(proxyRes, req, res) {
        const cookies = proxyRes.headers['set-cookie'];
        if (cookies) {
          const modifiedCookies = cookies.map(cookie => {
            if (cookie.includes('Path=/refresh')) {
              return cookie.replace('Path=/refresh', 'Path=/api/refresh');
            }
            return cookie;
          });
          proxyRes.headers['set-cookie'] = modifiedCookies;
        }
      }
    })
  );
};

后端 Flask 保持原有 JWT_REFRESH_COOKIE_PATH = "/refresh" 配置不变,这样:

  • 直连 Flask 的请求,Cookie Path 为 /refresh,浏览器正常发送
  • React 代理请求时,响应中的 Cookie 被修改为 /api/refresh,前端请求 /api/refresh 时会自动携带

通过请求上下文判断来源,在生成 Refresh Cookie 时动态设置 Path。可以通过检查 Referer 头或自定义请求头区分代理请求。

修改 Flask 代码:

from flask import Flask, request
from flask_jwt_extended import JWTManager, create_refresh_token, set_refresh_cookies

app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'your-secret-key'
jwt = JWTManager(app)

# 移除固定的 JWT_REFRESH_COOKIE_PATH 配置
@app.route('/login', methods=['POST'])
def login():
    refresh_token = create_refresh_token(identity='user123')
    response = {"msg": "login success"}
    
    # 通过 Referer 判断是否来自 React 代理
    if request.referrer and 'localhost:3000' in request.referrer:
        set_refresh_cookies(response, refresh_token, path='/api/refresh')
    else:
        set_refresh_cookies(response, refresh_token, path='/refresh')
    
    return response

@app.route('/refresh', methods=['POST'])
def refresh():
    return {"msg": "refresh success"}

if __name__ == '__main__':
    app.run(port=5000)

若担心 Referer 头被禁用,可让前端在代理请求时添加自定义头(如 X-Proxy-Source: react),后端通过 request.headers.get('X-Proxy-Source') 判断。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:55:25