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

Flask API后端+HTML+jQuery前端的CSRF防护最佳实现方式是什么?

不用改前端成Jinja模板完全没问题!我之前也遇到过类似的场景,给你一套轻量的实现方案,不用依赖Flask-WTF,纯手动搞定CSRF防护:

1. 先配置Flask的核心密钥

首先确保你的Flask应用已经设置了SECRET_KEY,因为我们要借助加密的session来存储CSRF token,这是基础要求:

from flask import Flask, session

app = Flask(__name__)
# 建议从环境变量读取,别硬编码在代码里
app.config['SECRET_KEY'] = 'your-secure-secret-key-here'
2. 写一个接口给前端获取CSRF Token

我们需要生成安全的随机token并存在session中,同时提供一个GET接口让前端拿到这个token:

import secrets
from flask import jsonify

@app.route('/api/csrf-token', methods=['GET'])
def get_csrf_token():
    # 如果session里没有token,就生成一个16字节的随机字符串
    if 'csrf_token' not in session:
        session['csrf_token'] = secrets.token_hex(16)
    return jsonify({'csrf_token': session['csrf_token']})

用secrets模块生成的随机字符串比random更安全,适合做安全凭证。

3. 前端用jQuery自动携带Token

页面加载时先获取token,然后通过全局AJAX配置,让所有修改型请求自动带上token到请求头:

// 页面加载完成后获取CSRF token
let csrfToken;
$(document).ready(function() {
    $.get('/api/csrf-token')
        .done(function(res) {
            csrfToken = res.csrf_token;
        });
});

// 全局配置AJAX,给非GET请求自动添加CSRF请求头
$.ajaxSetup({
    beforeSend: function(xhr) {
        if (csrfToken && this.method !== 'GET') {
            xhr.setRequestHeader('X-CSRFToken', csrfToken);
        }
    }
});

这样不管是POST/PUT/DELETE的AJAX请求,都会自动带上X-CSRFToken头,不用每个请求手动写。

4. 后端全局验证Token

用Flask的before_request钩子,对所有非幂等请求(也就是会修改数据的请求)做Token验证:

from flask import request, jsonify

@app.before_request
def validate_csrf_token():
    # GET/HEAD/OPTIONS这类只读请求不需要CSRF防护
    safe_methods = ['GET', 'HEAD', 'OPTIONS']
    if request.method not in safe_methods:
        # 从请求头拿到前端传的token
        received_token = request.headers.get('X-CSRFToken')
        # 和session里存储的token比对
        if not received_token or received_token != session.get('csrf_token'):
            return jsonify({'error': 'Invalid or missing CSRF token'}), 403

如果token不匹配或者缺失,直接返回403禁止访问,拦截恶意请求。

额外小贴士
  • 如果是跨域场景,需要配合Flask-CORS,设置supports_credentials=True,同时前端AJAX要加xhrFields: {withCredentials: true},这样session才能正常传递。
  • 用户登录成功后,建议重新生成CSRF token(删除旧的再生成新的),避免token复用带来的风险。
  • 如果有非AJAX的表单提交,可以把token放在隐藏的<input>里,后端从request.form.get('csrf_token')获取验证,原理和请求头一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:57:12