gpt4 book ai didi

asp.net-mvc - 是否可以/正确地在一个页面中以两种不同的形式使用多个 @Html.AntiForgeryToken() ?

转载 作者:行者123 更新时间:2023-12-03 22:21:58 26 4
gpt4 key购买 nike

我在 @Html.AntiForgeryToken() 方面遇到了严重的问题。我有一个注册 Controller ,它有一个创建 View 来创建/注册新成员。因此,我在主提交表单中使用了 @Html.AntiForgeryToken() ,而没有使用任何 SALT。现在,我想在用户名文本框的模糊事件中验证用户名是否已存在于数据库中。对于此验证,我编写了一个名为“Validation”的新 Controller ,并编写了一个带有常量验证 SALT 的方法:

 [HttpPost]
[ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)]
public ActionResult username(string log) {
try {
if (log == null || log.Length < 3)
return Json(log, JsonRequestBehavior.AllowGet);

var member = Membership.GetUser(log);

if (member == null) {
//string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}";
if (Regex.IsMatch(log, userPattern))
return Json(log, JsonRequestBehavior.AllowGet);
}

} catch (Exception ex) {
CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
return Json(log, JsonRequestBehavior.AllowGet);
}
//found e false
return Json(log, JsonRequestBehavior.AllowGet);

}

方法运行良好。我已经检查了没有 [ValidateAntiForgeryToken] 的 HTTP Get 注释,它给了我预期的结果。

我用谷歌搜索并检查了许多给定的解决方案,但这些解决方案都不起作用。对于我的验证 Controller ,我在同一页面中使用了另一个表单,并在防伪 token 中使用了 SALT。

示例:主提交表单的第一个防伪 token :

@using (Html.BeginForm("Create", "Register")) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) ... }

第二个防伪 token :

<form id="__AjaxAntiForgeryForm" action="#" method="post">
@Html.AntiForgeryToken(SALT)
</form>

在 javascript 中我使用了这个

<script type="text/javascript" defer="defer">
$(function () {
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};

if ($("#LogName").length > 0) {

$("#LogName").blur(function () {
var user = $("#LogName").val();
var logValidate = "/Validation/username/";
//var URL = logValidate + user;
//var token = $('#validation input[name=__RequestVerificationToken]').val();
data = AddAntiForgeryToken({ log: user });

$.ajax({
type: "POST",
dataType: "JSON",
url: logValidate,
data: data,
success: function (response) {
alert(response);
}
});

});

}
});
</script>

在我的 Firebug 中我得到了这个:

log=admin&__RequestVerificationToken=NO8Kds6B2e8bexBjesKlwkSexamsruZc4HeTnFOlYL4Iu6ia%2FyH7qBJcgHusekA50D7TVvYj%2FqB4eZp4VDFlfA6GN5gRz7PB%2ByZ0AxtxW4nT0E%2FvmYwn7Fvo4GzS2ZAhsGLyQC098dfIJaWCSiPcc%2FfD00FqKxjvnqmxhXvnEx2Ye83LbfqA%2F4XTBX8getBeodwUQNkcNi6ZtAJQZ79ySg%3D%3D

已传递,但在 cookie 部分我得到了一个与传递的 cookie 不同的 cookie:实际 Cookie:

ws5Dt2if6Hsah rW2nDly P3cW1smIdp1Vau 0TXOK1w0ctr0BCso/nbYu w9blq/QcrXxQLDLAlKBC3Tyhp5ECtK MxF4hhPpzoeByjROUG0NDJfCAlqVVwV5W6lw9ZFp/VBcQmwBCzBM/36UTBWmWn6pMM2bqnyoqXOK4aUZ4=

我认为这是因为我在一个页面中使用了 2 个防伪 token 。但在我看来,我应该使用 2,因为第一个是为提交而生成的,下一个需要验证验证。然而,这是我的猜测,我认为我错了,因此我需要你们的帮助。

谁能解释一下我应该使用两种防伪还是一种防伪的事实?

先谢谢大家了......

最佳答案

经过8个小时的努力,终于找到了解决办法。

首先,是的,在页面中使用 2 个防伪 token 并没有什么坏处。其次,不需要将 cookie 与提供的 token 进行匹配。提供的 token 始终不同,并将在服务器中进行验证。

如果我们使用[HttpGet] Action 动词,防伪 token 就不起作用。因为在防伪验证过程中, token 是通过检索请求中的 Request.Form['__RequestVerificationToken'] 值。引用:Steven Sanderson's blog: prevent cross...

解决方案:

我修改 Controller :

[HttpPost]

[ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)]
//change the map route values to accept this parameters.
public ActionResult username(string id, string __RequestVerificationToken) {
string returnParam = __RequestVerificationToken;

try {
if (id == null || id.Length < 3)
return Json(returnParam, JsonRequestBehavior.AllowGet);

var member = Membership.GetUser(id);

if (member == null) {
//string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}";
if (Regex.IsMatch(id, userPattern))
return Json(returnParam, JsonRequestBehavior.AllowGet);
}

} catch (Exception ex) {
CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
return Json(returnParam, JsonRequestBehavior.AllowGet);
}
//found e false
return Json(returnParam, JsonRequestBehavior.AllowGet);
}

同一页面中我的第一个表单:

@using (Html.BeginForm("Create", "Register")) {

@Html.AntiForgeryToken(ApplicationEnvironment.SALT)

@Html.ValidationSummary(true)
....
}

同一页面中我的第二个表单:

**<form id="validation">
<!-- there is harm in using 2 anti-forgery tokens in one page-->
@Html.AntiForgeryToken(ApplicationEnvironment.SALT)
<input type="hidden" name="id" id="id" value="" />
</form>**

我的 jQuery 来解决这个问题:

 $("#LogName").blur(function () {
var user = $("#LogName").val();
var logValidate = "/Validation/username/";
$("#validation #id").val(user);
**var form = $("#validation").serialize(); // a form is very important to verify anti-forgery token and data must be send in a form.**

var token = $('input[name=__RequestVerificationToken]').val();

$.ajax({
**type: "POST", //method must be POST to validate anti-forgery token or else it won't work.**
dataType: "JSON",
url: logValidate,
data: form,
success: function (response) {
alert(response);
}
});
});

关于asp.net-mvc - 是否可以/正确地在一个页面中以两种不同的形式使用多个 @Html.AntiForgeryToken() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12341725/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com