如何用MVC AntiForgeryToken做一个AJAX帖子



这个删除按钮只会在我删除ValidateAntiForgeryToken属性时调用控制器方法。如何更改这两种方法中的任何一种来保留防伪令牌?我假设。net不相信这种删除方式是安全的,并导致AJAX无法命中控制器。我想找到一种最安全的方式来发送删除调用。

删除按钮AJAX。

$("table").on("click", ".btn-delete", function (e) {
var thisId = $(this).data('id');
if (confirm("Are you sure you want to delete this item?")) {
$.post('/AdminPortal/Client/Delete/', { id: thisId }, function (data) {
window.location.href = "/AdminPortal/Client/Index";
});
}
});

删除方法控制器

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Delete(string id)
{
//add priv check here in the future
var client = baseSvc.ClientRepo.GetById(long.Parse(id));
if (client != null)
{
client.IsActive = false;
baseSvc.ClientRepo.Save(client);
}
return RedirectToAction(nameof(Index), new { area = nameof(AdminPortal) });
}

我的代码中有如下内容:

全局JavaScript函数

// CSRF (XSRF) security
function addAntiForgeryToken(data) {
//if the object is undefined, create a new one.
if (!data) {
data = {};
}
//add token
var tokenInput = $('input[name=__RequestVerificationToken]');
if (tokenInput.length) {
data.__RequestVerificationToken = tokenInput.val();
}
return data;
};

in my_Layout.cshtml(每一页都有)

@Html.AntiForgeryToken()

使用:然后在做你的POST之前,你可以调用这个方法来添加一个令牌到你的数据:

let data = addAntiForgeryToken({ id: thisId });
$.post('/AdminPortal/Client/Delete/', data, function (response) {
window.location.href = "/AdminPortal/Client/Index";
});

我已经浪费了几个小时试图在。net 7中修复这个问题。有许多解决方案,但对于。net 6之前的版本,它们不再具有功能。唯一有效的解决方案——实际上非常简单——是在服务器端设置防伪报头的名称,然后通过post headers在客户端设置它:

  1. 在服务器端,包括以下内容:

    builder.Services.AddAntiforgery(x => x.HeaderName = "X-ANTI-FORGERY-TOKEN");
    

    可选地,添加自动验证,或者手动添加控制器方法上的装饰器:

    builder.Services.AddControllersWithViews(options =>
    {               
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
    })
    
  2. 在客户端,添加以下内容:

    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
    {
    @Html.AntiForgeryToken()
    }
    
  3. 在post方法(Axios, jQuery等)中,获取元素值,然后将其分配给标题。我用Axios:

    let tokenInput = document.querySelector('input[name=__RequestVerificationToken]');
    let token = tokenInput.value;
    let customConfig = {
    headers: {
    'Content-Type': 'application/json',
    'X-ANTI-FORGERY-TOKEN': token //note the same name given before
    }
    };
    axios.post(url, data, customConfig).then....//whatever
    

最新更新