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 相关路径时发送,同时支持两种场景:
- 直接向 Flask 发起
http://localhost:5000/refresh请求 - 从 React 应用发起
http://localhost:3000/api/refresh请求,经代理转发到 Flask 的/refresh
已尝试方案
- 动态设置 Cookie 路径:请求到达 Flask 时路径均为
/refresh,无法区分是否来自代理 - 修改
JWT_REFRESH_COOKIE_PATH为"/api/refresh":仅 React 场景正常,Swagger 直连场景失效 - 修改代理匹配所有路径:导致 React 应用被重定向到 Flask 的 5000 端口,前端无法正常运行
解决方案
方案一:代理层修改 Cookie 路径(推荐)
利用 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时会自动携带
方案二:Flask 动态设置 Cookie 路径
通过请求上下文判断来源,在生成 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
相关产品推荐
相关产品推荐

