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

.NET Core 2 API中AutoValidateAntiforgeryToken持续返回400错误求助

解决.NET Core 2 API + Vue.js的XSRF令牌400错误问题

看起来你已经走对了方向,但可能在配置细节上有遗漏——我之前也遇到过类似的问题,下面一步步帮你排查和修复:

1. 确认后端Antiforgery的核心配置

.NET Core默认的Antiforgery Cookie名称和Header名称和你用的Angular风格不一致,必须手动指定匹配的名称,否则后端根本识别不了你发送的令牌。

在Startup.cs的ConfigureServices方法里,添加Antiforgery的自定义配置:

services.AddAntiforgery(options =>
{
    // 和你设置的Cookie名称一致
    options.Cookie.Name = "XSRF-TOKEN";
    // 匹配前端发送的Header名称
    options.HeaderName = "X-XSRF-TOKEN";
    // 允许前端读取Cookie(必须设为false,否则JS拿不到)
    options.Cookie.HttpOnly = false;
    // 根据你的部署环境调整SameSite:跨域用None+Secure,同域用Lax/Strict
    options.Cookie.SameSite = SameSiteMode.Lax;
    // 生产环境建议开启Secure(仅HTTPS)
    options.Cookie.Secure = Environment.IsProduction();
});

2. 修正登录接口的令牌生成逻辑

你提到登录后创建了XSRF-TOKENCookie,但要确保生成的是Antiforgery组件认可的令牌,而不是自定义随便生成的字符串。修改登录Action:

[HttpPost("login")]
public async Task<IActionResult> Login(LoginModel model)
{
    // 这里是你的登录验证逻辑,比如验证用户名密码、生成JWT等
    var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false);
    if (!result.Succeeded)
    {
        return BadRequest("登录失败");
    }

    // 获取Antiforgery服务并生成令牌
    var antiforgery = HttpContext.RequestServices.GetRequiredService<IAntiforgery>();
    var tokens = antiforgery.GetAndStoreTokens(HttpContext);
    
    // 将RequestToken存入Cookie(这就是前端要读取的XSRF令牌)
    Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions
    {
        HttpOnly = false,
        Path = "/", // 确保整个应用都能访问到Cookie
        SameSite = SameSiteMode.Lax,
        Secure = Environment.IsProduction(),
        Expires = DateTimeOffset.UtcNow.AddHours(2) // 设置合理的过期时间
    });

    return Ok("登录成功");
}

3. 完善Vue前端的请求拦截器

确保你正确读取了Cookie,并且请求携带了Credentials(跨域时必须):

首先添加一个Cookie读取工具函数,避免直接解析document.cookie出错:

function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}

然后配置axios的拦截器和全局Credentials:

import axios from 'axios';

// 全局开启携带Cookie(跨域时必须)
axios.defaults.withCredentials = true;

// 请求拦截器:自动添加X-XSRF-TOKEN头
axios.interceptors.request.use(config => {
    const xsrfToken = getCookie('XSRF-TOKEN');
    if (xsrfToken) {
        config.headers['X-XSRF-TOKEN'] = xsrfToken;
    }
    return config;
}, error => {
    return Promise.reject(error);
});

4. 检查CORS配置(如果是跨域场景)

如果你的Vue应用和API不在同一个域名下,必须正确配置CORS允许Credentials和自定义Header:

在Startup.cs的ConfigureServices里:

services.AddCors(options =>
{
    options.AddPolicy("AllowVueClient", builder =>
    {
        builder.WithOrigins("http://localhost:8080") // 替换成你的Vue应用地址
               .AllowAnyMethod()
               .AllowAnyHeader()
               .AllowCredentials(); // 必须开启,否则浏览器不会发送Cookie
    });
});

然后在Configure方法里,确保CORS中间件的顺序正确(要在UseAuthentication和UseAuthorization之前):

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("AllowVueClient"); // 这里要放在认证授权前面
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

5. 最后验证几个关键点

  • 确认你的请求是POST/PUT/DELETE这类非安全方法(AutoValidateAntiforgeryToken会自动跳过GET/HEAD/OPTIONS请求)
  • 检查浏览器的开发者工具:在登录后,Application标签里是否能看到XSRF-TOKENCookie,且Path为/
  • 查看请求头:发送受保护的请求时,是否携带了X-XSRF-TOKEN头,且值和Cookie一致
  • 如果是跨域且用了HTTPS,把SameSite设为SameSiteMode.None,同时Secure设为true(Chrome等现代浏览器要求SameSite=None的Cookie必须是Secure)

按照这些步骤调整后,应该就能解决400错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:03:12