.NET后端Web API与Vue前端集成Antiforgery Token遇400错误求助
.NET + Vue CSRF验证400 Bad Request问题修复
问题根源诊断
- 异步操作时序错误:前端调用
fetchCsrfToken()后立刻同步读取Cookie并设置请求头,此时后端的Cookie响应还未生效,导致请求头携带的是空或无效Token。 - Antiforgery Token配对逻辑错误:.NET的Antiforgery机制需要Cookie Token(默认存储在HttpOnly Cookie)和Request Token(前端通过请求头/表单提交)配对验证,你的实现混淆了两种Token的用途,且自定义Cookie配置未匹配Antiforgery的识别规则。
修复步骤
1. 修正后端Antiforgery配置与Token生成逻辑
修改Startup.cs,明确指定Antiforgery的Cookie和请求头名称,同时保持Cookie的HttpOnly属性(防止XSS窃取):
public override void ConfigureServices(IServiceCollection services) { ... services.AddControllersWithViews(); // 配置Antiforgery参数 services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN"; // 前端请求头携带的Token名称 options.Cookie.Name = "CSRF-COOKIE"; // 存储Cookie Token的Cookie名 options.Cookie.Secure = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.Strict; options.Cookie.HttpOnly = true; // Cookie Token禁止JS访问,保障安全 }); ... }
修改Controller.cs的Token生成接口,让Antiforgery自动管理Cookie Token,仅返回Request Token给前端:
private readonly IAntiforgery _antiForgery; // 通过构造函数注入IAntiforgery public YourController(IAntiforgery antiForgery) { _antiForgery = antiForgery; } [HttpGet("csrf-token")] [AllowAnonymous] public IActionResult GetCsrfToken() { // 生成Token对:Cookie Token自动写入响应Cookie,Request Token返回给前端 var tokens = _antiForgery.GetAndStoreTokens(HttpContext); // 直接返回Request Token,无需手动写入Cookie return Ok(new { csrfToken = tokens.RequestToken }); } [HttpPost("submit-data")] [ValidateAntiForgeryToken] public IActionResult CreateResource() { return Ok(); }
2. 修正前端异步逻辑与Token携带方式
修改main.js,确保在成功获取Request Token后再设置请求头并发送验证请求:
import './assets/main.css' import { createApp } from 'vue' import App from './App.vue' import axios from 'axios'; // 带CSRF Token的POST请求 async function sendData(csrfToken) { try { const response = await axios.post( 'https://localhost:5001/authenticate/submit-data', {}, { headers: { 'X-CSRF-TOKEN': csrfToken } } ); console.log('Response:', response.data); } catch (error) { console.error('Error posting data:', error); } } // 初始化CSRF Token并执行请求 async function initCsrfFlow() { try { const tokenRes = await axios.get('https://localhost:5001/authenticate/csrf-token'); const csrfToken = tokenRes.data.csrfToken; // 设置全局默认请求头,供后续所有请求复用 axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken; // 发送需要验证的POST请求 await sendData(csrfToken); } catch (error) { console.error('CSRF初始化失败:', error); } } // 应用启动时执行初始化流程 initCsrfFlow(); createApp(App).mount('#app')
关键说明
- .NET Antiforgery的核心验证逻辑:必须同时存在Cookie中的Token和请求头/表单中的Token,两者配对成功才会通过验证。
- Cookie Token必须设为HttpOnly,避免被XSS攻击窃取;Request Token由前端主动携带,无需存入Cookie。
- 异步操作必须保证时序:必须等待后端返回Request Token后,再携带该Token发送需要验证的请求。
内容的提问来源于stack exchange,提问作者Alessandro Conti
相关产品推荐
相关产品推荐

