You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:34:50