为什么我在授权过滤器中获得的防伪令牌与我在浏览器中看到的令牌不同?



在我的应用程序中,我使用@Html.AntiForgeryToken()来装饰表单,然后我通过继承IAuthorizationFilter来实现一个CustomAuthorizationFilter,它有一个检查AntiForgery操作方法的方法,包括Ajax调用。

这是我的防伪检查方法:

private static void CheckForAntiForgery(HttpRequestBase request)
{
var cookie = request.Cookies["__RequestVerificationToken"];
if (cookie != null)
{
var cookieToken = cookie.Value;
var formToken = request.Headers["__RequestVerificationToken"];
AntiForgery.Validate(cookieToken, formToken);
}
}

我正在使用 Ajax 调用保存方法并将form.serialize()作为数据发送。我在浏览器中检查了$('[name=__RequestVerificationToken]').val() 的值,看到"form.serialize()">正在获取该值。但是,当我进入上述方法时,"formToken">与我在浏览器中看到的有所不同。表单令牌在发送回应用程序后是否经过一些额外的处理?

另一个问题,在同一页面上,我尝试了多次保存点击,同时我看到每次$('[name=__RequestVerificationToken]').val()的值发生变化时,我在上述方法中获得的formToken都没有改变。这有什么原因吗,或者我在实施防伪令牌检查时遗漏了一些东西?

非常感谢。

我相信__RequestVerificationToken不会改变。

下面的示例代码在使用 ajax 的 asp.net 身份登录中对我有用。 希望这有帮助。

if (form.valid()) {
$(this).addClass('ladda-button');
var l = Ladda.create(this);
l.start();
var form1 = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form1).val();
$.ajax({
type: 'POST',
url: '/Account/Login',
data: {
__RequestVerificationToken: token,
Email: $('#username').val(),
Password: $('#password').val(),
RememberMe: false,
},
success: function (result) {
if (result.id === 1) {
mynotify('<div class="alert alert-success media fade in"><p><strong>success!</strong> ' + result.name + '</p></div>');
window.location.href = "\";
} else if (result.id === 4) {
mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Login failed..</p></div>');
} else {
mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> ' + result.name + '</p></div>');
}
},
error: function (result) {
mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Critical error occured, contact administrator</p></div>');
console.log(result);
}
});
l.stop();
} else {
$('body').addClass('boxed');
mynotify('<div class="alert alert-danger media fade in"><p><strong>Error!</strong> Please try again.</p></div>');
}

事实证明,formToken与我在浏览器中看到的有所不同,因为请求没有通过ajax发送令牌并继续使用旧令牌。我没有在数据中发送令牌,而是在发送事件之前将其移动到 ajax:

var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
type: "POST",
url: newurl,
beforeSend: function (request)
{
request.setRequestHeader("__RequestVerificationToken", token);
},
data: form.serialize(),
datatype: "JSON",
success: function..,
error: function..
})

现在,每次发送新请求时,它都会选取新令牌。

最新更新