在.NET 3.1与ReactJS中解决CSRF/XSRF验证400错误的方案
.NET 3.1 + React 集成XSRF验证400错误解决方案
问题核心
你的场景中,[ValidateAntiForgeryToken]返回400的本质是:.NET的防伪造验证需要Cookie中的__RequestVerificationToken和请求头中的令牌值配对验证,当前配置只定义了头名称,但缺失令牌的生成、传递全流程。
具体修复步骤
1. 调整Startup的防伪造配置
确保Cookie允许跨域读取、JS可访问,同时指定头名称:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Antiforgery; public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddCors(options => { options.AddPolicy("AllowReactApp", builder => { builder.WithOrigins("http://localhost:3000") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // 必须加这个,跨域请求才能携带Cookie }); }); services.AddAntiforgery(options => { options.HeaderName = "X-XSRF-TOKEN"; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.HttpOnly = false; // 允许JS读取Cookie,方便React提取令牌 options.Cookie.SecurePolicy = CookieSecurePolicy.None; // 本地HTTP测试用,生产环境改为Always }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseCors("AllowReactApp"); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
2. 添加令牌获取接口
客户端需要先拿到令牌,才能在POST请求中携带:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Antiforgery; [ApiController] [Route("[controller]")] public class DataController : ControllerBase { private readonly IAntiforgery _antiforgery; public DataController(IAntiforgery antiforgery) { _antiforgery = antiforgery; } // 获取XSRF令牌接口 [HttpGet] [Route("/api/get-xsrf-token")] public IActionResult GetXsrfToken() { var tokens = _antiforgery.GetAndStoreTokens(HttpContext); // 将令牌写入Cookie,同时返回令牌值(可选,也可让客户端自己从Cookie读取) Response.Cookies.Append("X-XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false, SameSite = SameSiteMode.None, Secure = false }); return Ok(new { token = tokens.RequestToken }); } [HttpPost] [Route("/api/data")] [ValidateAntiForgeryToken] public IActionResult GetData() { var data = new { message = "Data from API" }; return Ok(data); } }
3. React端请求逻辑调整
必须携带凭据(Cookie),并在请求头中加入令牌:
// 获取XSRF令牌 async function getXsrfToken() { await fetch('http://localhost:xxxx/api/get-xsrf-token', { credentials: 'include' // 强制携带Cookie }); // 从Cookie中提取令牌 const token = document.cookie.split('; ') .find(row => row.startsWith('X-XSRF-TOKEN=')) ?.split('=')[1]; return token; } // 调用POST接口 async function callDataApi() { const token = await getXsrfToken(); const response = await fetch('http://localhost:xxxx/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-XSRF-TOKEN': token }, credentials: 'include', // 携带Cookie供.NET验证 body: JSON.stringify({}) // 按需传递业务参数 }); const data = await response.json(); console.log(data); }
4. 清理冗余代码
删除注释掉的AntiforgeryMiddleware相关代码,[ValidateAntiForgeryToken]特性和自定义中间件功能重复,选其一即可,避免重复验证冲突。
关键注意事项
- 本地HTTP测试时,
CookieSecurePolicy必须设为None,否则Cookie不会被传递 - React请求的
credentials: 'include'是跨域携带Cookie的关键,不能省略 - .NET自动维护的
__RequestVerificationTokenCookie无需手动处理,只要客户端携带Cookie,验证机制会自动读取配对
内容的提问来源于stack exchange,提问作者Deepak Malviya
相关产品推荐
相关产品推荐

