开启JWT_COOKIE_CSRF_PROTECT后Flask POST请求失败,如何解决?
解决方案:Flask-JWT-Extended CSRF保护下POST请求失败问题
当JWT_COOKIE_CSRF_PROTECT = True时,Flask-JWT-Extended会对非GET请求强制校验CSRF令牌,你的POST请求失败就是因为没有携带正确的CSRF令牌。以下是完整解决步骤:
1. 后端配置调整
确保你的Flask配置包含以下项(补充原有配置):
CSRF_ENABLED = True CORS_SUPPORTS_CREDENTIALS = True JWT_TOKEN_LOCATION = ['cookies'] # 开启JWT Cookie CSRF保护(生产环境必须设为True) JWT_COOKIE_CSRF_PROTECT = True # 允许CSRF令牌存储在Cookie中(默认开启,可明确配置) JWT_CSRF_IN_COOKIES = True # 指定允许的前端域名,替换为你的Vue应用实际地址 CORS_ORIGINS = ["http://localhost:8080"]
可选:添加一个接口用于前端获取CSRF令牌(若前端无法直接读取Cookie时使用):
from flask import jsonify from flask_jwt_extended import get_csrf_token @app.route("/api/csrf-token", methods=["GET"]) def get_csrf_token(): return jsonify({"csrf_token": get_csrf_token()})
2. 前端Axios配置修改
前端需要读取Flask设置的csrf_access_token Cookie,并在非GET请求的请求头中携带X-CSRF-TOKEN字段:
方法一:全局配置Axios(推荐)
安装js-cookie简化Cookie读取(也可使用原生document.cookie):
npm install js-cookie
在Vue项目的Axios全局配置中添加拦截器:
import axios from 'axios'; import Cookies from 'js-cookie'; // 全局开启携带凭证 axios.defaults.withCredentials = true; // 请求拦截器:自动为非GET请求添加CSRF令牌 axios.interceptors.request.use(config => { if (config.method !== 'get') { config.headers['X-CSRF-TOKEN'] = Cookies.get('csrf_access_token'); } return config; }); // 你的POST请求可简化为: const path1 = `/limit_engine/balance`; axios.post(path1) .then(response => { console.log(response.data.balance); }) .catch(error => { console.error(error); });
方法二:单个请求手动添加令牌
如果不需要全局配置,可在单个POST请求中手动设置请求头:
import Cookies from 'js-cookie'; const path1 = `/limit_engine/balance`; axios.post(path1, {}, { withCredentials: true, headers: { 'X-CSRF-TOKEN': Cookies.get('csrf_access_token') } }) .then(response => { console.log(response.data.balance); }) .catch(error => { console.error(error); });
关键原理说明
当JWT_COOKIE_CSRF_PROTECT = True时,Flask-JWT-Extended会在用户登录(或生成JWT令牌)时自动将CSRF令牌存入名为csrf_access_token的Cookie中。前端必须将该令牌通过X-CSRF-TOKEN请求头传递给后端,后端才会通过CSRF校验,允许POST等非GET请求通过。
内容的提问来源于stack exchange,提问作者adam
相关产品推荐
相关产品推荐

