asp.net core 必须注册 addantiforgery() 服务,否则 token 生成验证失败;跨域需配置 cookie.domain 和 samesite;razor 表单中 token 必须置于 form 内;api 需显式添加 [validateantiforgerytoken];前后端分离时需手动获取、存储并携带 requestverificationtoken 头。

ASP.NET Core 中启用 Antiforgery 服务是必须的
不注册服务,后续所有 Token 生成和验证都会失败。在 Program.cs(.NET 6+)中必须调用 AddAntiforgery(),否则 IAntiforgery 注入会报 InvalidOperationException。
默认配置已足够应对多数场景,但要注意:如果前端部署在不同域名(如 app.example.com 和 api.example.com),需显式设置 Cookie.Domain 和 Cookie.SameSite:
builder.Services.AddAntiforgery(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Strict; // 或 Lax,根据跨站表单需求权衡
options.Cookie.Domain = ".example.com";
});
漏设 SameSite 是生产环境 Token 验证失败的常见原因,尤其在 Chrome 80+ 后默认策略收紧。
在 Razor 页面或 MVC 视图中正确输出 AntiForgeryToken()
Token 必须放在 <form></form> 内部、且与提交目标一致的页面上,否则后端验证时会因上下文不匹配而拒绝请求。
以下写法是安全且标准的:
常见错误包括:
- 把
@Html.AntiForgeryToken()放在<form></form>外——Token 不会被提交 - 用 AJAX 提交但没手动读取并携带
RequestVerificationToken请求头 - 在多个嵌套表单中重复使用同一 Token(虽不报错,但违背设计意图)
API 控制器需要显式添加 [ValidateAntiForgeryToken] 特性
MVC 控制器默认不校验 Token,哪怕视图里写了 @Html.AntiForgeryToken()。必须对接受非 GET 的 Action 显式标注:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(UserModel model)
{
// ...
}
注意点:
-
[ValidateAntiForgeryToken]只检查XSRF-TOKENCookie +RequestVerificationToken请求头(或表单字段),不检查 JWT 或其他认证凭据 - 若 API 同时支持浏览器表单和移动端调用,建议按 User-Agent 或路由前缀分流,避免移动端因无 Cookie 而被拦截
- 不要在
[HttpGet]方法上加该特性——GET 本不该有副作用,加了反而阻碍缓存和预加载
前后端分离项目中手动管理 Token 的关键步骤
当使用 Vue/React 等前端框架时,无法依赖 @Html.AntiForgeryToken() 自动注入,必须由后端提供初始 Token,并由前端存储、携带。
推荐做法:
- 首次加载页面时,后端通过
IAntiforgery.GetAndStoreTokens()生成一对 Token(Cookie + 表单值),返回 JSON 给前端 - 前端将
RequestVerificationToken值存入内存(勿存 localStorage,防 XSS 泄露) - 每次 POST/PATCH/DELETE 请求,在 header 中带上:
headers['RequestVerificationToken'] = tokenValue - 后端控制器仍需标注
[ValidateAntiForgeryToken],框架会自动从 header 或 form 中提取比对
容易忽略的是:Token 有生命周期(默认 14 天),且每次调用 GetAndStoreTokens() 会刷新 Cookie。若前端长期不刷新 Token,可能遭遇“Token 已过期”验证失败。











