本文目录导读:

CSRF (Cross-Site Request Forgery) token是一种安全机制,用于保护Web应用免受跨站请求伪造攻击,以下是关于它的核心概念和实现方式:
什么是CSRF攻击?
攻击者通过诱导用户点击链接或加载恶意页面,在用户已登录目标网站的情况下,伪造请求(如转账、修改密码)发送到目标服务器,从而执行非用户本意的操作。
CSRF Token的工作原理
- 生成阶段:服务器为每个用户会话生成一个唯一的、随机的token(通常存储在session或cookie中)
- 传递阶段:服务器将token嵌入到表单的隐藏字段或请求头中
- 验证阶段:当提交敏感请求时,服务器验证提交的token是否与当前会话中的token一致
实现示例(Spring Security)
前端(Thymeleaf模板)
<form action="/transfer" method="POST">
<!-- 自动嵌入CSRF token -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<input type="text" name="amount" />
<button type="submit">转账</button>
</form>
AJAX请求(JavaScript)
// 获取token(通常从meta标签或cookie中)
const csrfToken = document.querySelector('meta[name="_csrf"]').content;
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;
fetch('/api/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
[csrfHeader]: csrfToken // 如 X-CSRF-TOKEN
},
body: JSON.stringify({ amount: 1000 })
});
后端验证(Spring Security自动处理)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 存储到cookie
.and()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated();
}
}
CSRF Token的存储与传递方式
| 方式 | 说明 | 适用场景 |
|---|---|---|
| 隐藏表单字段 | 嵌入HTML表单 | 传统表单提交 |
| 请求头 | 通过自定义HTTP头传递 | AJAX/API请求 |
| Cookie | 设置HttpOnly=false的Cookie,前端读取后添加到请求 | SPA应用(需额外注意安全) |
为什么CSRF Token能防御攻击?
- 同源策略:攻击者无法从其他域读取目标网站的Cookie或页面内容
- 随机性:token足够随机,无法预测
- 会话绑定:每个用户/会话的token不同,无法复用
常见注意事项
- 不要在URL参数中传递token:容易泄露(Referer头)
- 敏感操作使用POST/PUT/DELETE:GET请求不应修改服务器状态
- 同步器模式:token与用户会话绑定,不是全局固定值
- 双重提交Cookie:替代方案,将token同时放在Cookie和请求中验证
现代替代方案
- SameSite Cookie属性:设置为Lax或Strict可防御大部分CSRF
- 自定义请求头:如
X-Requested-With: XMLHttpRequest - Origin/Referer验证:检查请求来源
实际开发中,CSRF Token仍然是Web应用最广泛使用的防御手段之一,尤其适用于传统多页面应用(MPA),对于API服务,更推荐结合OAuth2 Token和CORS策略。