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

ASP.NET Core中Ajax请求后更新AntiForgeryToken的技术问询

实现ASP.NET Core Ajax请求的“每次验证+令牌刷新”方案

刚好之前做过类似的需求,完美匹配你要的「每次请求用新令牌、旧令牌失效」的安全要求,给你一套完整的实现步骤:

一、后端配置与接口改造

首先确保AntiForgery服务配置正确(默认已配置,但可以明确指定请求头名称,和前端对齐):

builder.Services.AddAntiforgery(options =>
{
    options.HeaderName = "X-CSRF-TOKEN"; // 自定义请求头名称,前后端要一致
    options.Cookie.Name = ".AspNetCore.Antiforgery.MyApp"; // 可选:自定义Cookie名,方便排查
});

接下来改造你的API接口,核心是验证当前令牌→处理业务→生成新令牌并返回:

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private readonly IAntiforgery _antiforgery;

    public MyController(IAntiforgery antiforgery)
    {
        _antiforgery = antiforgery;
    }

    [HttpPost("submit")]
    public async Task<IActionResult> SubmitData([FromBody] YourRequestModel model)
    {
        // 1. 验证当前请求的AntiForgeryToken
        try
        {
            await _antiforgery.ValidateRequestAsync(HttpContext);
        }
        catch
        {
            return BadRequest("无效的防伪令牌,请重试");
        }

        // 2. 处理你的业务逻辑(比如存数据、计算等)
        // ...

        // 3. 生成新的防伪令牌,覆盖旧令牌(旧令牌会自动失效)
        var newTokens = _antiforgery.GetAndStoreTokens(HttpContext);
        
        // 两种方式返回新令牌:选一种就行
        // 方式1:放到响应Header里
        Response.Headers.Append("X-New-CSRF-TOKEN", newTokens.RequestToken);
        // 方式2:放到返回的JSON数据里
        return Ok(new { 
            Success = true,
            Message = "提交成功",
            NewCsrfToken = newTokens.RequestToken
        });
    }
}

二、前端Ajax逻辑调整

前端要做的就是拿当前令牌发请求→收到响应后更新令牌→下次请求用新令牌,用jQuery举个例子(原生JS同理):

// 初始化:从页面的隐藏字段拿到初始令牌
let currentCsrfToken = $('input[name="__RequestVerificationToken"]').val();

// 封装通用Ajax请求函数
function sendAjax(data) {
    $.ajax({
        url: '/api/my/submit',
        method: 'POST',
        contentType: 'application/json',
        headers: {
            'X-CSRF-TOKEN': currentCsrfToken // 带上当前有效的令牌
        },
        data: JSON.stringify(data),
        success: function(res) {
            // 更新令牌:从返回的JSON或Header里取都行
            currentCsrfToken = res.NewCsrfToken;
            // 或者从Header取:currentCsrfToken = this.getResponseHeader('X-New-CSRF-TOKEN');
            
            // 同步更新页面上的隐藏字段,避免页面刷新后令牌失效
            $('input[name="__RequestVerificationToken"]').val(currentCsrfToken);
            
            // 处理业务成功逻辑
            alert(res.Message);
        },
        error: function(xhr) {
            alert(xhr.responseText || '请求失败');
        }
    });
}

// 绑定按钮点击事件
$('#submit-btn').on('click', function() {
    const requestData = { /* 你的请求参数 */ };
    sendAjax(requestData);
});

三、关键细节提醒

  • 初始令牌来源:在Razor视图里通过@Html.AntiForgeryToken()生成隐藏字段,页面加载时就能拿到初始令牌。
  • 令牌失效逻辑:调用GetAndStoreTokens会生成新的令牌并关联到当前会话,旧令牌会自动失效,不需要额外存储已使用的令牌(ASP.NET Core内部会处理会话绑定的令牌有效性)。
  • 前后端对齐:请求头名称一定要和后端配置的HeaderName完全一致,否则验证会失败。

这样就能实现你要的「每次请求用新令牌、旧令牌无法重复使用」的安全机制了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:11:34