Flask后端与Vue.js前端集成时,如何获取并在请求中使用CSRF令牌
Flask后端与Vue.js前端集成时,如何获取并在请求中使用CSRF令牌
我来帮你搞定Flask和Vue结合时的CSRF令牌问题,其实核心就是让Flask把令牌传递给Vue,再让Vue的请求自动带上它就行,咱们一步步来:
一、先搞定Flask端的令牌暴露
首先你得确保Flask的CSRF保护是正常开启的(Flask-WTF默认已经开启,但一定要配置好SECRET_KEY,这个是基础)。接下来要把令牌传递给Vue,有两种简单的方式:
方法1:通过页面Meta标签传递(推荐)
在Flask渲染的Vue入口页面(比如你挂载Vue的index.html模板)里,添加一个Meta标签,把CSRF令牌塞进去:
<!DOCTYPE html> <html> <head> <!-- 这里添加CSRF令牌的Meta标签 --> <meta name="csrf-token" content="{{ csrf_token() }}"> </head> <body> <div id="app"></div> <!-- 你的Vue打包后的JS文件 --> <script src="/static/js/app.js"></script> </body> </html>
这种方式不用额外发请求,Vue初始化时就能直接拿到令牌。
方法2:通过API接口返回令牌
如果你的Vue是完全独立的单页应用,也可以写个简单的Flask接口返回令牌:
@app.route("/api/csrf-token") def get_csrf_token(): # 直接返回CSRF令牌的JSON数据 return jsonify({'csrf_token': csrf_token()})
不过这种需要Vue启动时先调用这个接口拿令牌,稍微麻烦一点,还是第一种更省心。
二、Vue端配置Axios自动携带令牌
因为你用的是Axios,最好全局配置一下,让所有请求都自动带上CSRF令牌,不用每次手动加。
全局配置Axios(推荐)
在Vue的入口文件(比如main.js)里,或者你的组件初始化时,添加以下代码:
import axios from "axios"; // 从Meta标签里获取CSRF令牌 const csrfToken = document.querySelector('meta[name="csrf-token"]').content; // 配置Axios全局默认请求头,让所有请求都带上CSRF令牌 axios.defaults.headers.common['X-CSRFToken'] = csrfToken; // 或者用请求拦截器,更灵活(比如可以根据请求类型动态处理) axios.interceptors.request.use(config => { // 只在POST/PUT/DELETE等修改请求里加令牌,GET请求不需要 if (['post', 'put', 'delete'].includes(config.method)) { config.headers['X-CSRFToken'] = csrfToken; } return config; });
结合你的组件代码修改
配置完全局Axios后,你组件里的handleSubmit方法就不用手动加headers了,直接发送请求就行:
// 你的Vue组件script部分 import axios from "axios"; export default { data() { return { formData: { username: "", email: "", password: "", confirm: "", }, errors: [] }; }, methods: { async handleSubmit() { try { // 先做前端验证 if (this.formData.password !== this.formData.confirm) { this.errors = ["Passwords do not match"]; return; } // 直接发送请求,Axios会自动带上CSRF令牌头 const response = await axios.post( "http://127.0.0.1:5000/api/register", this.formData ); if (response.data.success) { this.$router.push({ name: "login" }); } else { this.errors = [response.data.message]; } } catch (error) { console.error(error); this.errors = [ "An error occurred while processing your request. Please try again later.", ]; } }, }, };
三、关键注意事项
- Flask端的CSRF识别:Flask-WTF默认会检查
X-CSRFToken请求头,或者表单里的csrf_token字段,所以咱们用X-CSRFToken头是完全没问题的。 - 跨域场景处理:如果你的Vue和Flask运行在不同端口(比如Vue在8080,Flask在5000),需要安装
flask-cors库并配置允许携带凭证:
同时Axios要设置from flask_cors import CORS app = Flask(__name__) # 允许跨域请求,并且支持携带Cookie/自定义头 CORS(app, supports_credentials=True)withCredentials: true:axios.defaults.withCredentials = true; - 令牌的时效性:CSRF令牌默认是和用户会话绑定的,只要会话有效,令牌就有效,不用频繁刷新。
备注:内容来源于stack exchange,提问作者Adel Brizini
相关产品推荐
相关产品推荐

