.net 6 mvc AntiForgeryToken 验证失败

.net 6 mvc AntiForgeryToken fails to verify

提问人:YiCheng Wang 提问时间:9/27/2023 最后编辑:Qing GuoYiCheng Wang 更新时间:9/27/2023 访问量:98

问:

我正在开发一个 .net 6 MVC Web 应用程序作为前端,将 .net 6 Web API 项目作为后端。

有一个函数可以进行 AJAX POST 调用来获取数据,并且它与请求中的 a 一起顺利工作。令牌与其他参数一起放置在数据中。控制器中的断点按预期触发。@Html.AntiForgeryToken()

视图:(非常确定这是此视图中唯一的令牌)

@Html.AntiForgeryToken()

Ajax:(这工作正常)

function ProductSearch() {
    var token = $(':input:hidden[name*="RequestVerificationToken"]');
    $.ajax({
        type: 'POST',
        url: '@Url.Content("~/MyController/SearchProduct")',
        data: {
            __RequestVerificationToken: token.val(),
            data: $('#data').val()
        },
        success: function (res) {
            if (res.IsSuccess === false) {
                Swal.fire({
                    icon: 'error',
                    title: res.Message,
                    showConfirmButton: true
                })
            }
            else {                        
                $("#divToBeReplaced").html('');
                $("#divToBeReplaced").html(res);
            }
        },
        error: function (xhr, textStatus, error) {
            CloseLoading();
            Swal.fire({
                icon: 'error',
                title: 'error',
                showConfirmButton: true,
                timer: 1500
            })
        }
    })
}

控制器操作:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SearchProduct(string? data)
{
        ...
}

但是,我正在处理的另一个 AJAX 请求,使用上面提到的相同请求,无法发布到控制器,并立即收到 HTTP 400 错误。 与之前的 AJAX 类似,CSRF 令牌被放置在 AJAX 数据中: (尝试将其放入标题中,但仍然失败)@Html.AntiForgeryToken()

var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
    type: 'POST',
    url: '@Url.Content("~/MyController/DeleteCheckedProduct")',
    beforeSend: function (request) {
        request.setRequestHeader('RequestVerificationToken', token);
    },
    data: {
        __RequestVerificationToken: token,
        delList: delList
    },
    ...

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteCheckedProduct(string delList)
{
    ...
}

也许设置会影响我的 AJAX 帖子?Program.cs

builder.Services.AddControllersWithViews(options =>
{
    //options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); → commented
})
.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = null;
    options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.WriteAsString;
});


正如你所看到的,这似乎是一个简单的问题,两个 Ajax 函数几乎相同,我仍然无法弄清楚为什么第二个 AJAX 无法请求。任何线索将不胜感激,谢谢!

尝试发送没有 DeleteCheckedProduct Action 属性的 post 请求,它工作得很好。[ValidateAntiForgeryToken]

编辑:还发现只成功了第一次尝试。当我再次触发此函数时,我也收到了 HTTP 400 错误。 为了您的信息,返回一个 PartialView。当 AJAX 请求成功时,返回的部分视图将替换现有的 like . 我猜部分视图有什么东西吗?ProductSearch()MyController/SearchProduct $("#divToBeReplaced").html(res);

ajax ASP.NET-CORE . NET-6.0 AntiforgeryToken

评论

0赞 Qing Guo 9/27/2023
在第一个 AJAX 中,您设置了 ,但在第二个 ajax 中,您设置了 尝试使用 。__RequestVerificationToken: token.val(),request.setRequestHeader('RequestVerificationToken', token);token.val()
0赞 YiCheng Wang 9/27/2023
@QingGuo 感谢您提醒我错过发布的参数,已经在上面编辑了我的问题。变量已签名tokentoken$('input[name="__RequestVerificationToken"]').val();
0赞 Qing Guo 9/27/2023
“当我再次触发此函数时,我也收到了 HTTP 400 错误。”您的错误信息是什么?尝试使用 to 查看源代码选项卡中的代码,并在 处设置断点,再次触发此函数时可以看到该值吗?F12__RequestVerificationToken: token.val(),
0赞 YiCheng Wang 9/27/2023
@QingGuo 是的,我可以看到令牌值,当我执行两个 AJAX 请求时,令牌值是相同的。400 错误消息如下:“POST localhost:7213/MyController/DeleteCheckedProduct 400 send @ jquery.min.js:2 ajax @ jquery.min.js:2 DeleteCheckedProduct @ MyController:323 onclick @ MyController:1” 我尝试搜索一些信息,但仍然只表明错误来自 AJAX 调用,没有任何用处。
0赞 Qing Guo 9/27/2023
我看不到链接内容。如果您添加了最小的可重现示例,则更容易分辨。我不确定,在这个阶段。

答:

0赞 Qing Guo 9/27/2023 #1

由于脚本在名为 的标头中发送令牌,因此在 Program.cs 中,配置防伪服务以查找标头:RequestVerificationTokenRequestVerificationToken

builder.Services.AddAntiforgery(o => o.HeaderName = "RequestVerificationToken");

评论

0赞 Qing Guo 9/27/2023
这是工作吗?如果没有,你在哪里定义这个ajax?此外,您还可以使用 在源代码选项卡中查看代码,并设置断点 at 以查看令牌值。F12request.setRequestHeader('RequestVerificationToken', token);
0赞 YiCheng Wang 9/27/2023
Ajax 请求位于该部分中,该部分位于我定义 .此外,我尝试修改 AntiForgeryToken 的标头名称以匹配我的 AJAX 调用,但仍然请求失败,出现 HTTP 400 错误。<scripts>@Html.AntiForgeryToken()