所需的防伪表单字段“__RequestVerificationToken”不存在 用户注册错误

Posted

技术标签:

【中文标题】所需的防伪表单字段“__RequestVerificationToken”不存在 用户注册错误【英文标题】:The required anti-forgery form field "__RequestVerificationToken" is not present Error in user Registration 【发布时间】:2013-04-12 17:58:09 【问题描述】:

我正在使用Membership.create用户函数,然后出现以下错误,

所需的防伪表单字段“__RequestVerificationToken”是 不存在

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

我是这样解决的

[AttributeUsage(AttributeTargets.Method)]
public class ExcludeFromAntiForgeryValidationAttribute : Attribute

并将System.Web.Helpers.AntiForgery.Validate(cookie != null ? cookie.Value : null, formToken) 置于 if 条件中

bool shouldValidate =!filterContext.ActionDescriptor.GetCustomAttributes(typeof(ExcludeFromAntiForgeryValidationAttribute), true).Any();
if (shouldValidate)
    System.Web.Helpers.AntiForgery.Validate(cookie != null ? cookie.Value : null, formToken);

【讨论】:

【参考方案2】:

在我的情况下,我在发布 AJAX 帖子时遇到了这个错误,结果证明__RequestVerificationToken 值没有在调用中传递。我必须手动查找该字段的值并将其设置为发送到端点的数据对象的属性。

data.__RequestVerificationToken = $('input[name="__RequestVerificationToken"]').val();

示例

HTML

  <form id="myForm">
    @html.AntiForgeryToken()

    <!-- other input fields -->

    <input type="submit" class="submitButton" value="Submit" />
  </form>

Javascript

$(document).on('click', '#myForm .submitButton', function () 
  var myData =  ... ;
  myData.__RequestVerificationToken = $('#myForm input[name="__RequestVerificationToken"]').val();

  $.ajax(
    type: 'POST',
    url: myUrl,
    data: myData,
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    dataType: 'json',
    success: function (response) 
      alert('Form submitted');
    ,
    error: function (e) 
      console.error('Error submitting form', e);
      alert('Error submitting form');
    ,
  );
  return false; //prevent form reload
);

控制器

[HttpPost]
[Route("myUrl")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> MyUrlAsync(MyDto dto)

    ...

【讨论】:

事实上,如果你定义你的 MyDto 类的结构,那将会很有帮助 好吧,我不确定它是否真的很有帮助,示例代码现在早已不复存在,所以让我们说public class MyDto public bool Whatever get; set; 这完全取决于你如何准备myData。如果您正在使用myData=$('myForm').serialize(),它应该可以正常工作。【参考方案3】:

使用个人用户帐户的 ASP.NET 默认登录在 Chrome 中出现此错误

.cshtml:

@using (Html.BeginForm("Login", "Account", new  ReturnUrl = ViewBag.ReturnUrl , FormMethod.Post, new  @class = "form-horizontal", role = "form" ))

    @Html.AntiForgeryToken()
    <h4>Use a local account to log in.</h4>

控制器:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

通过清除站点数据解决:

【讨论】:

好的,它的工作。但这种情况一次又一次地发生。在 Firefox 中,相同的项目运行正常。我能做什么? @CanÜrek 您是否有多个具有相同域的不同项目/站点?例如本地主机、app.site.com 和 app2.site.com 等?它通常因此发生。【参考方案4】:

有时您正在编写带有结果列表的表单操作方法。在这种情况下,您不能使用一种操作方法。所以你必须有两个同名的动作方法。一个带有[HttpGet],另一个带有[HttpPost] 属性。

在您的[HttpPost] 操作方法中,设置[ValidateAntiForgeryToken] 属性并将@Html.AntiForgeryToken() 放入您的html 表单中。

【讨论】:

【参考方案5】:

在我的情况下,这是由于在 webconfig 中将 requireSSL=true 添加到 httpcookies 导致 AntiForgeryToken 停止工作。示例:

<system.web>
  <httpCookies httpOnlyCookies="true" requireSSL="true"/>
</system.web>

为了使requireSSL=true@Html.AntiForgeryToken() 都能正常工作,我在Global.asaxApplication_BeginRequest 中添加了这一行

    protected void Application_BeginRequest(object sender, EventArgs e)
  
    AntiForgeryConfig.RequireSsl = HttpContext.Current.Request.IsSecureConnection;
  

【讨论】:

【参考方案6】:

在我的例子中,我在提交表单上有这个 javascript

$('form').submit(function () 
    $('input').prop('disabled', true);
);

这是从正在提交的表单中删除隐藏的 RequestVerificationToken。我将其更改为:

$('form').submit(function () 
    $('input[type=submit]').prop('disabled', true);
    $('input[type=text]').prop('readonly', true);
    $('input[type=password]').prop('readonly', true);
);

...而且效果很好。

【讨论】:

您是如何注意到禁用输入时反键影响的? @Cer - 如果你问我是怎么注意到的,我用 fiddler 检查了请求,发现没有发送密钥。我读到 Html 提交的内容不包括禁用的控件。所以我把它改成了readonly 并排除了隐藏控件。似乎工作得很好。【参考方案7】:

这里的所有其他答案也是有效的,但如果它们都不能解决问题,那么检查实际的标头是否正在传递给服务器也是值得的。

例如,在 nginx 后面的负载均衡环境中,默认配置是在将请求传递到服务器之前剥离 __RequestVerificationToken 标头,请参阅:simple nginx reverse proxy seems to strip some headers

【讨论】:

【参考方案8】:

对于我们这些人来说,上传文件作为请求的一部分的另一种可能性。如果内容长度超过&lt;httpRuntime maxRequestLength="size in kilo bytes" /&gt;并且您正在使用请求验证令牌,浏览器将显示'The required anti-forgery form field "__RequestVerificationToken" is not present' 消息而不是请求长度超出消息。

将 maxRequestLength 设置为足以满足请求的值可以解决眼前的问题 - 尽管我承认这不是一个合适的解决方案(我们希望用户知道文件大小的真正问题,而不是请求验证令牌的问题不见了)。

【讨论】:

【参考方案9】:

因为这是第一次搜索这个:

我只在 Internet Explorer 中遇到过这个问题,但无法弄清楚问题所在。长话短说,它没有保存令牌的 cookie 部分,因为我们的(子)域中有一个下划线。在 Chrome 中工作,但 IE/Edge 不喜欢它。

【讨论】:

【参考方案10】:

我想分享我的,我一直在关注这个anti forgerytoken tutorial 使用带有 angularjs 的 asp.net mvc 4,但每次我使用 $http.post 请求时都会引发异常,我发现解决方案只是添加 'X-Requested-With': 'XMLHttpRequest' 到 $http.post 的标题,因为它看起来像 (filterContext.HttpContext.Request.IsAjaxRequest()) 不将其识别为 ajax,这是我的示例代码。

App.js

var headers = 'X-Requested-With': 'XMLHttpRequest', 'RequestVerificationToken': $scope.token, 'Content-Type': 'application/json; charset=utf-8;' ;

$http( method: 'POST', url: baseURL + 'Save/User', data: JSON.stringify($scope.formData), headers: headers ).then(function (values) alert(values.data); ).catch(function (err) console.log(err.data); );


保存控制器

[HttpPost] [MyValidateAntiForgeryToken] public ActionResult User(UserModel usermodel) ....

【讨论】:

【参考方案11】:

在我的几个控制器上的 EPiServer 解决方案中,在接受 HttpGet 的 Index 操作上有一个 ContentOutputCache 属性。这些操作的每个视图都包含一个表单,该表单将 HttpPost 操作发布到同一控制器或不同控制器。 一旦我从所有这些索引操作中删除该属性,问题就消失了。

【讨论】:

【参考方案12】:

确保在你的控制器中有你的 http 属性,例如:

[HttpPost]

还要在控制器中添加属性:

[ValidateAntiForgeryToken]

在你的视图中你必须写:

@Html.AntiForgeryToken();

我有 Html.AntiForgeryToken();如果在代码块中没有 @ 符号,它在 Razor 中不会出错,但在运行时会出错。 确保查看@Html.Ant.. 的@ 符号是否缺失

【讨论】:

【参考方案13】:

如果有人因为我遇到的相同原因遇到错误,这是我的解决方案:

如果你有Html.AntiForgeryToken();

改成@Html.AntiForgeryToken()

【讨论】:

【参考方案14】:

在我的情况下,web.config 中用于 cookie 的域不正确是原因:

<httpCookies domain=".wrong.domain.com" />

【讨论】:

耶!如果您在本地计算机上键入 那么只有在本地计算机上的 cookie 才会起作用,如果您尝试在其他计算机上打开您的站点,您将输入它的 ip(fe 192.168.1.43),因为它不起作用它正在寻找“本地主机”【参考方案15】:

可能导致这种情况(刚刚遇到这种情况)的另一件事是: 如果您出于某种原因禁用表单中的所有输入字段。 它将禁用包含您的验证令牌的隐藏输入字段。 当表单将被发回时,令牌值将丢失,并将生成丢失的错误。所以你需要做的是重新启用保存验证令牌的输入字段,一切都会好起来的。

【讨论】:

【参考方案16】:

就我而言,我的 web.config 中有这个:

&lt;httpCookies requireSSL="true" /&gt;

但我的项目设置为不使用 SSL。注释掉该行或将项目设置为始终使用 SSL 解决了它。

【讨论】:

在我的情况下,web.config 有 requireSSL,但端口 80 和 443 都有 IIS 绑定,因此输入 https 的用户得到正确的行为,输入 http 的用户得到这个错误,需要重写强制所有人到 https://HTTP_HOST/R:1 的规则已修复 谢谢? 在我的情况下,IIS 有这个绑定 (https » EmptyHostName » IP » 443) 但没有绑定 (https » www.mysite.com » IP » 443)。因此,我为https 添加了一个非空主机名 的新绑定,该绑定等于域,它解决了问题。我也重写了IIS 中的设置来强制http 2 https【参考方案17】:

即使未启用 Cookie,您也会收到错误消息。

【讨论】:

成功了。我使用的是 Internet Explorer。使用 Chrome 浏览器为我解决了这个问题 这也解决了我的问题。在谷歌浏览器中启用 cookie。谢谢【参考方案18】:

像这样:

控制器

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MethodName(FormCollection formCollection)

     ...
     Code Block
     ...

视图:

@using(Html.BeginForm())

     @Html.AntiForgeryToken()
     <input name="..." type="text" />
     // rest

【讨论】:

尝试仅在 HTML 中使用【参考方案19】:

还要确保避免使用 [ValidateAntiForgeryToken] 在 [HttpGet] 下。

  [HttpGet]
  public ActionResult MethodName()
  
  ..
  

【讨论】:

这个答案补充了其他答案并解决了我的问题!谢谢 这个答案假设您没有保存任何提交的数据(您不应该在 HttpGet 上)。如果是,那么您仍然需要 [ValidateAntiForgeryToken] 提供的 XSRF 保护。【参考方案20】:

您在操作之前有[ValidateAntiForgeryToken] 属性。您还应该在表单中添加@Html.AntiForgeryToken()

【讨论】:

我有一个网页也有同样的问题,但一切都是正确的。出了什么问题。 @ConductedClever 您应该使用 fiddler 和/或 firebug(任何浏览器开发工具)仔细检查所有内容(字段、cookie),看看这篇文章:asp.net/web-api/overview/security/… @ConductedClever 我也是。这是工作,但很少得到这个错误,我不知道为什么? 我一切正常,在我的测试中它工作正常,在客户端的机器上它直到最近才工作,但现在它给出了这个错误。我不知道为什么。请问除了这里列出的之外,还有其他的想法吗? Html.AntiForgeryToken(); 不起作用!!变成@Html.AntiForgeryToken() 作品

以上是关于所需的防伪表单字段“__RequestVerificationToken”不存在 用户注册错误的主要内容,如果未能解决你的问题,请参考以下文章

所需的防伪表单字段 __requestverificationtoken 不存在 ajax 调用时出错

ajax 调用中不存在所需的防伪表单字段“__RequestVerificationToken”

从 ajax 方法调用操作引发错误:所需的防伪表单字段“__RequestVerificationToken”不存在

jmeter中的相关问题:所需的防伪形式字段“__RequestVerificationToken”不存在

所需的防伪 cookie“__RequestVerificationToken”不存在

更新面板 webcontrol 所需的表单字段