CSRF Token 是什么
CSRF Token 是服务端生成、与用户会话绑定的随机值,用于区分『用户自己发起的请求』和『第三方站点诱导浏览器发起的请求』。流程是:服务端生成令牌并下发到页面,前端在提交时回传,服务端比对与会话中保存的值是否一致。它的有效性取决于随机性、与会话的绑定关系以及轮换时机;把令牌放在 URL 查询串里,或全站长期复用同一个值,都会让防护效果大打折扣。
基本信息
| 生成要求 | 密码学安全随机源,长度通常不少于 16 字节 |
|---|---|
| 绑定方式 | 与会话或用户身份绑定,不跨用户复用 |
| 下发位置 | 表单隐藏域或页面 meta 标签,前端读入自定义请求头 |
| 校验时机 | 所有改变状态的请求(POST/PUT/DELETE) |
| 轮换时机 | 登录成功后重新生成,配合会话标识轮换 |
典型使用场景
- 传统表单站点为每个表单嵌入隐藏字段,提交时由服务端比对
- 前后端分离项目把令牌写入 meta 标签,前端读取后放入自定义请求头
- 单页应用配合 SameSite Cookie 形成双层防护,浏览器兼容性与令牌校验互为补充
- 登录、改密、转账等敏感操作单独校验并叠加二次确认
- 接口开放场景评估是否改用其他机制(如自定义头 + 同源校验)
实现要点(伪代码)
实现要点(伪代码)
生成:密码学安全随机(>=16 字节),与会话绑定
下发:表单隐藏域或 meta 标签,前端读取后放入自定义头
校验:服务端比对会话中保存的值,不一致直接返回 403
轮换:登录成功后重新生成,同时轮换会话标识
范围:所有改变状态的请求都要校验,GET 不产生副作用前端附加请求头示例
前端附加请求头示例
// 令牌放在页面 meta 中,前端读取后附加到请求头
const token = document.querySelector('meta[name=csrf-token]').content;
fetch('/api/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token, // 服务端据此与会话中的值比对
},
credentials: 'same-origin', // 携带 Cookie 但限定同源
body: JSON.stringify(payload),
});令牌不要放在 URL 查询串:它会进入访问日志、Referer 头与浏览器历史,等于把校验凭据公开在多个位置。
纯接口服务若只提供自定义请求头且不允许跨域携带凭据,攻击难度本身较高;此时仍建议保留同源校验或令牌机制,避免后续放开跨域时留下缺口。