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

ASP.NET Core 7 + React 项目Antiforgery Token失效问题求助

ASP.NET Core 7 + React 实现Antiforgery防护的问题修复

现有代码的核心问题

  • Program.cs中AddAntiforgery存在语法错误,且属性名使用错误
  • 未提供生成反伪造令牌的GET端点,React请求的GET /Test2不存在(Test2仅定义了Post方法)
  • React端获取令牌的逻辑错误:令牌存储在Cookie中而非响应JSON,且请求头直接传入函数而非实际令牌值
  • 跨域场景下未配置CORS允许携带Cookie和自定义请求头

修复步骤

1. 修正Program.cs的Antiforgery及CORS配置

// 配置Antiforgery
builder.Services.AddAntiforgery(options =>
{
    options.Cookie.Name = "X-XSRF-TOKEN";
    options.HeaderName = "X-XSRF-TOKEN"; // 注意正确属性名是HeaderName,不是Header
    options.Cookie.SameSite = SameSiteMode.Lax; // 跨域场景建议设为Lax或None(None需配合Secure)
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS环境下启用
});

// 配置CORS(跨域场景必填)
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowReact", policy =>
    {
        policy.WithOrigins("http://localhost:3000") // 替换为你的React项目地址
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // 允许携带Cookie
    });
});

var app = builder.Build();

// 启用CORS(需放在UseRouting之后,UseAuthorization之前)
app.UseCors("AllowReact");

app.UseAuthorization();
app.MapControllers();
app.Run();

2. 添加生成反伪造令牌的GET端点

在Controller中新增一个专门的GET接口,用于触发令牌写入Cookie:

[Route("/api/csrf-token")]
[HttpGet]
[IgnoreAntiforgeryToken] // 该端点无需验证,仅用于生成令牌
public IActionResult GetCsrfToken()
{
    var antiforgery = HttpContext.RequestServices.GetRequiredService<IAntiforgery>();
    antiforgery.GetAndStoreTokens(HttpContext); // 将令牌写入Cookie
    return Ok();
}

3. 修正React端的令牌获取与请求逻辑

// 从Cookie中提取XSRF令牌的工具函数
const getCsrfTokenFromCookie = () => {
    const cookies = document.cookie.split('; ');
    const csrfCookie = cookies.find(c => c.startsWith('X-XSRF-TOKEN='));
    return csrfCookie ? decodeURIComponent(csrfCookie.split('=')[1]) : '';
};

// 初始化时触发令牌生成(写入Cookie)
useEffect(() => {
    fetch("https://localhost:7277/api/csrf-token", {
        method: "GET",
        credentials: "include" // 必须添加,否则Cookie不会被浏览器保存
    });
}, []);

const handleSubmit = async (e) => {
    e.preventDefault();
    const csrfToken = getCsrfTokenFromCookie();
    
    try {
        const res = await fetch("https://localhost:7277/Test2", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "X-XSRF-TOKEN": csrfToken
            },
            credentials: "include", // 携带Cookie
            body: JSON.stringify({
                "vehicleReg": inputValue.current.value
            })
        });
        
        if (!res.ok) {
            throw new Error(`请求失败:${res.status}`);
        }
        
        const data = await res.json();
        console.log("发送成功", data);
    } catch (er) {
        console.log("请求出错", er);
    }
};

4. 全局配置Antiforgery验证(可选)

如果希望所有POST/PUT/DELETE请求自动验证令牌,可在Program.cs中全局配置,无需每个Controller方法添加[ValidateAntiForgeryToken]:

builder.Services.AddControllers(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

关键注意事项

  • 跨域场景下,CORS的AllowCredentials必须开启,同时React的fetch请求要添加credentials: "include"
  • Antiforgery Cookie的SameSite和Secure属性需根据部署环境调整(本地HTTP可设SameSiteMode.Lax、CookieSecurePolicy.None)
  • 令牌由ASP.NET Core写入Cookie,前端只需从Cookie提取后放入请求头即可

内容的提问来源于stack exchange,提问作者user2038084

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:23:23