Ajax 请求如何加上 CSRF 防护
                           
天天向上
发布: 2025-06-28 12:51:59

原创
108 人浏览过

Ajax 请求中加上 CSRF 防护 是非常重要的,特别是在现代 Web 应用(如使用 jQuery、Axios、Fetch 的前后端分离项目)中。下面是从原理、实现方法、代码示例到不同框架下的用法。


一、CSRF Token 在 Ajax 中的处理原理

在传统表单中,CSRF token 是通过隐藏字段提交的。而在 Ajax 中:

  • 前端:需将 CSRF Token 加入请求 header 或请求 body;
  • 后端:需从 header 或 body 中提取并验证 token;
  • 通常由后端渲染页面时注入 token 到 HTML,再由 JavaScript 读取使用。

二、实现方式汇总

方法说明安全性
自定义 header(推荐)将 token 写入 Ajax 请求 header⭐⭐⭐⭐⭐
请求 body适用于 POST 请求带 form-data/json⭐⭐⭐⭐
Cookie + header 双 token(SPA/REST)防御 CSRF + XSS⭐⭐⭐⭐⭐

三、CSRF Token 在页面中的注入方式

方法 1:后端渲染注入到 meta 标签

<meta name="csrf-token" content="<?php echo $_SESSION['csrf_token']; ?>">

方法 2:注入到 JavaScript 变量

<script>
  window.csrfToken = "<?php echo $_SESSION['csrf_token']; ?>";
</script>

四、jQuery 示例:自动添加 CSRF Token

// 获取 token
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

// 全局设置 Ajax 请求头
$.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': token
  }
});

然后你就可以安全发送 POST 请求了:

$.post('/api/update-profile', {
  name: 'John'
}, function (response) {
  console.log('响应:', response);
});

五、原生 Fetch 示例

const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

fetch('/api/update-profile', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-TOKEN': token
  },
  body: JSON.stringify({ name: 'Jane' })
})
.then(res => res.json())
.then(data => console.log(data));

六、Axios 示例(推荐用于 Vue/React)

import axios from 'axios';

axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

axios.post('/api/update-profile', { name: 'Jane' })
  .then(response => console.log(response.data));

七、后端 PHP 中验证 Ajax 请求的 CSRF Token

session_start();

$csrf_token_header = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';

if (!hash_equals($_SESSION['csrf_token'], $csrf_token_header)) {
    http_response_code(403);
    echo json_encode(['error' => 'CSRF 验证失败']);
    exit;
}

✅ 注意:X-CSRF-TOKEN 是常用自定义 header 名,可自由定义为如 X-XSRF-TOKEN


八、各主流框架的 Ajax CSRF 配置方式

🔸 Laravel

<!-- layout.blade.php -->
<meta name="csrf-token" content="{{ csrf_token() }}">

JS:

axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

Laravel 会自动验证 X-CSRF-TOKEN header 或 _token 字段。


🔸 Symfony

使用 CsrfTokenManager 生成令牌,手动验证:

$token = $request->headers->get('X-CSRF-TOKEN');
if (!$csrfTokenManager->isTokenValid(new CsrfToken('action_id', $token))) {
    throw new AccessDeniedHttpException('CSRF token invalid');
}

🔸 Yii2

开启 CSRF:

'request' => [
    'enableCsrfValidation' => true,
    'csrfParam' => '_csrf',
],

JS:

let csrfToken = $('meta[name=csrf-token]').attr("content");
$.ajaxSetup({
    data: { _csrf: csrfToken }
});

📚 权威参考资料


小结:Ajax 防 CSRF 最佳实践

步骤推荐做法
1️⃣ 页面注入 token用 meta 或 JS 全局变量
2️⃣ 前端带上 token使用 header X-CSRF-TOKEN
3️⃣ 后端验证 token与 Session 或 Cookie 中 token 比对
4️⃣ 验证失败处理返回 403,记录日志

更多详细内容,请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *