Asp.net mvc 防伪令牌问题的疑难解答
我有一个表单帖子,总是给我一个防伪令牌错误 这是我的表格:Asp.net mvc 防伪令牌问题的疑难解答,asp.net-mvc,asp.net-mvc-3,antiforgerytoken,Asp.net Mvc,Asp.net Mvc 3,Antiforgerytoken,我有一个表单帖子,总是给我一个防伪令牌错误 这是我的表格: @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.EditorFor(m => m.Email) @Html.EditorFor(m => m.Birthday) <p> <input type="submit" id="Go" value="Go" /> </p>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.EditorFor(m => m.Email)
@Html.EditorFor(m => m.Birthday)
<p>
<input type="submit" id="Go" value="Go" />
</p>
}
以下是web.config中的machineKey:
<system.web>
<machineKey validationKey="mykey" decryptionKey="myotherkey" validation="SHA1" decryption="AES" />
</system.web>
我已经读到,在HttpContext上更改用户将使令牌无效,但这里没有发生这种情况。HttpGet on my Join操作仅返回以下视图:
[HttpGet]
public ActionResult Join()
{
return this.View();
}
所以我不确定发生了什么。我到处搜索,似乎所有的东西都表明要么是machineKey在改变(应用程序周期),要么是用户/会话在改变
还可能发生什么?如何对此进行故障排除?您是在一台服务器上还是在一个web场上?如果是单个服务器,请在web.config中注释掉machineKey元素,然后作为基本起点重试。有变化吗?
此外,你能想到你的cookie被清除或过期的原因吗?它们也是正常工作所必需的 在Adam的帮助下,我将MVC源代码添加到我的项目中,并且能够看到有许多情况会导致相同的错误 以下是用于验证防伪令牌的方法:
public void Validate(HttpContextBase context, string salt) {
Debug.Assert(context != null);
string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
string cookieName = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath);
HttpCookie cookie = context.Request.Cookies[cookieName];
if (cookie == null || String.IsNullOrEmpty(cookie.Value)) {
// error: cookie token is missing
throw CreateValidationException();
}
AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value);
string formValue = context.Request.Form[fieldName];
if (String.IsNullOrEmpty(formValue)) {
// error: form token is missing
throw CreateValidationException();
}
AntiForgeryData formToken = Serializer.Deserialize(formValue);
if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {
// error: form token does not match cookie token
throw CreateValidationException();
}
string currentUsername = AntiForgeryData.GetUsername(context.User);
if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {
// error: form token is not valid for this user
// (don't care about cookie token)
throw CreateValidationException();
}
if (!String.Equals(salt ?? String.Empty, formToken.Salt, StringComparison.Ordinal)) {
// error: custom validation failed
throw CreateValidationException();
}
}
我的问题是,它将身份用户名与表单令牌的用户名进行比较。在我的例子中,我没有设置用户名(一个为null,另一个为空字符串)
虽然我怀疑许多人会遇到同样的情况,但希望其他人会发现,看到正在检查的基本条件,它会很有用。我刚刚遇到了一个问题,
@Html.AntiForgeryToken()
被调用了两次,因此反伪造令牌在HTTP Post有效负载中出错。我不知道您的意思是您能够按需获取错误,还是您在日志中看到了错误,但无论如何,这里有一种方法可以保证反伪造令牌错误
等等
- 确保您已注销,然后输入您的登录名
- 双击登录按钮
- 您将获得:
这可以在MVC4初始安装模板上复制。AntiForgeryToken还检查您登录的用户凭据是否未更改–这些凭据也在cookie中加密。您可以通过在global.asax.cs文件中设置
AntiForgeryConfig.suppressIdentityEuristicChecks=true
来关闭此功能 您应该防止双重表单提交。
我使用如下代码防止此类问题:
$('#loginForm').on('submit',function(e){
var $form = $(this);
if (!$form.data('submitted') && $form.valid()) {
// mark it so that the next submit can be ignored
$form.data('submitted', true);
return;
}
// form is invalid or previously submitted - skip submit
e.preventDefault();
});
或
另一个可能导致我出现此错误的原因是:我的一个表单中有两个
@Html.AntiForgeryToken()
一旦删除,问题就消失了。在禁用提交按钮之前,有必要检查表单是否有效
<script type="text/javascript">
//prevent double form submission
$('form', '#loginForm').submit(function () {
if ($(this).valid()) {
$(this).find(':submit').attr('disabled', 'disabled');
}
});
//防止双重表格提交
$('form','loginForm')。提交(函数(){
if($(this).valid()){
$(this.find(':submit').attr('disabled','disabled');
}
});
当我不得不将我的应用程序迁移到一台新机器上时,我也遇到了同样的问题。我不明白为什么会突然出现这个错误,但我确信它与迁移有关,所以我开始调查通过aspnet_reqsql注册数据库的情况,当这被消除后,我意识到这一定与注册应用程序有关,我确信我在类似的地方找到了答案。我在旅途中也发现有两种方法可以解决这个问题
无论您选择哪种方法都可以解决此问题,但我认为,未来迁移和服务器更改的最可靠方法是web.config中的唯一键,请记住,这将导致应用程序覆盖HKCU注册表配置单元并保持应用程序运行。html错误记录器不是正确的行
您必须检查页面中的所有加载值是否为非空。我刚刚遇到了类似的问题。我得到:
The required anti-forgery form field "__RequestVerificationToken" is not present.
有趣的是,我试着调试它,并在我希望在控制器中找到的两个地方看到了令牌
var formField = HttpContext.Request.Params["__RequestVerificationToken"];
var cookie = System.Web.HttpContext.Current.Request.Cookies["__RequestVerificationToken"].Value;
事实上,我应该看看这里:
var formField = HttpContext.Request.Form["__RequestVerificationToken"];
由于Params包含的不仅仅是表单字段,它还包含查询字符串、表单、Cookies和服务器变量
一旦那条红鲱鱼消失了,我发现防伪代币的形式不对 我在Mac上的Windows虚拟机上运行这个。但我呆在虚拟世界里。该服务器是由VisualStudio(2010)启动的开发服务器。我还使用主机头记录将“真实”URL路由到我的本地框(即,使实时URL指向我的本地框)。关于马赫数
The required anti-forgery form field "__RequestVerificationToken" is not present.
var formField = HttpContext.Request.Params["__RequestVerificationToken"];
var cookie = System.Web.HttpContext.Current.Request.Cookies["__RequestVerificationToken"].Value;
var formField = HttpContext.Request.Form["__RequestVerificationToken"];