所需的防伪cookie" __ RequestVerificationToken"不在场

时间:2015-10-23 16:04:29

标签: c# jquery asp.net-mvc cookies antiforgerytoken

我的网站每天大约提高20次此异常,通常表单工作正常,但有些情况会发生此问题而且我不知道为什么会这么随机。

这是elmah

记录的异常
  

500 HttpAntiForgery所需的防伪cookie __RequestVerificationToken"不存在。

但是它正在通过elmah

发送XML日志中显示的令牌
<form>
    <item name="__RequestVerificationToken">
      <value string="DNbDMrzHmy37GPS6IFH-EmcIh4fJ2laezIrIEev5f4vOhsY9T7SkH9-1b7GPjm92CTFtb4dGqSe2SSYrlWSNEQG1MUlNyiLP1wtYli8bIh41"/>
    </item>
    <item name="toPhone">
      <value string="XXXXXX"/>
    </item>
    <item name="smsMessage">
      <value string="xxxxxxxx"/>
    </item>
</form>

这是我在控制器上的方法,它使用数据属性来检查令牌是否有效或

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Send(SMSModel model)
{
    // my code goes here
}

这是我在视图上的表单

@using (Html.BeginForm("Send", "SMS", FormMethod.Post, new { @class = "form-sms", autocomplete = "off" }))
{
    @Html.AntiForgeryToken()
    <div class="row">
        <div class="col-md-12">
            <div class="form-group">
                <div class="input-group">
                    <div class="input-group-addon">+53</div>
                    @Html.TextBoxFor(m => m.toPhone, new { @class = "form-control", placeholder = "teléfono", required = "required", type = "tel", maxlength = 8 })
                </div>
            </div>
        </div>
    </div>
    <div class="form-group" style="position:relative">
        <label class="sr-only" for="exampleInputEmail3">Message (up to 135 characters)</label>
        @Html.TextAreaFor(m => m.smsMessage, new { rows = 4, @class = "form-control", placeholder = "escriba aquí su mensaje", required = "required", maxlength = "135" })
        <span class="char-count">135</span>
    </div>
    if (ViewBag.Sent == true)
    {
        <div class="alert alert-success alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <strong>Su mensaje ha sido enviado <span class="hidden-xs">satisfactoriamente</span></strong>
        </div>
    }
    if (ViewBag.Error == true)
    {
        <div class="alert alert-danger alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <strong>Error:</strong> Por favor revise el número de teléfono.
        </div>
    }
    <div class="errorToMany"></div>
    <button type="submit" class="btn btn-default btn-block">Enviar SMS</button>
}

这就是我如何使用AJAX发布我的数据

$('form.form-sms').submit(function (event) {
    $.ajax({
        url: $(this).attr("action"),
        type: "POST",
        data: $(this).serializeArray(),
        beforeSend: function (xhr) {
            $('.btn-default').attr("disabled", true);
            $('.btn-default').html("Enviando...")
        },
        success: function (data, textStatus, jqXHR) {
            if (data[0] == false && data[1] == "1") {
               some code 
            } else {
               location.reload();
            }
        },
        error: function (jqXHR, textStatus, errorThrown) { }
    });
    return false;
});

表单效果很好但是这个错误一直在发生,我不知道为什么,我已经在Stack Overflow上检查了其他问题,但没有任何对我有用。

有关我如何发布数据的进一步说明。

此发送短信的表格包含ToNumber和Message字段。当用户点击提交按钮时,AJAX函数接受控制并发布序列化表单的字段数据,当我在控制器中的函数完成并返回JSON结果表明一切顺利时,AJAX方法重新加载显示的页面用户成功的消息。

任何可能导致此问题的想法。

8 个答案:

答案 0 :(得分:20)

听起来好像事情按预期工作。

防伪帮助程序@Html.AntiForgeryToken()的工作方式是将一个名为__RequestVerificationToken的隐藏表单字段注入页面,并将cookie设置到浏览器中。

当表单被回发时,两者会进行比较,如果它们不匹配或者cookie丢失,则会抛出错误。

因此,Elmah记录表单正在发送__RequestVerificationToken并不重要。即使在CSRF攻击的情况下,它也会始终如此,因为这只是隐藏的表单字段。

<input name="__RequestVerificationToken" type="hidden" value="DNbDMrzHmy37GPS6IFH-EmcIh4fJ2laezIrIEev5f4vOhsY9T7SkH9-1b7GPjm92CTFtb4dGqSe2SSYrlWSNEQG1MUlNyiLP1wtYli8bIh41" />

另一方面,错误消息表示未发送相应的COOKIE

  

500 HttpAntiForgery所需的防伪cookie   __RequestVerificationToken&#34;不存在。

所以基本上某人/某事正在重播表单帖子而没有提出获取cookie的原始请求。因此,他们有隐藏的形式领域 __RequestVerificationToken但不是验证它的cookie。

所以看起来事情正如他们应该做的那样。检查您的日志:IP号码和推荐人等。在重定向表单内容时,您可能受到攻击或者可能正在做一些奇怪或错误的事情。如上所述,referrers是一个很好的开始这种错误的地方,假设这不是欺骗。

另请注意,根据MDN

location.reload();
  

Location.reload()方法从当前重新加载资源   URL。它的可选唯一参数是一个布尔值,当它是   true,导致始终从服务器重新加载页面。如果是   false或未指定,浏览器可能会重新加载页面   高速缓存

如果是,有时从缓存加载,那么最终可能会得到一个POST,其中包含旧页面令牌但不包含Cookie。

所以试试:

location.reload(true);

答案 1 :(得分:11)

最近遇到了类似的问题。 确实缺少防伪cookie,所以(正如其他人指出的那样)

  1. 服务器未将cookie添加到请求中,或
  2. 浏览器拒绝了它。
  3. 在我的情况下,它是服务器:我没有在本地环境中使用SSL,但在web.config我有以下行:

    <httpCookies requireSSL="True"/>
    

    在这种情况下,解决方案是切换到SSL,或者将值设置为“False”以用于本地环境。

答案 2 :(得分:7)

除了rism的优秀答案之外,遇到此错误的另一个可能原因是您的浏览器或浏览器插件阻止设置Cookie

答案 3 :(得分:1)

我在边缘浏览器中遇到了同样的问题。

我已通过更改浏览器设置解决了此问题。

按照说明解决问题:

转到设置>查看高级设置> Cookies>更改为“不阻止Cookies”。

关闭浏览器并检查。

我认为,这可能会对某人有所帮助。

答案 4 :(得分:1)

检查您是否错过了前端@ Html.AntiForgeryToken()中的这一行

答案 5 :(得分:0)

可能想看看这个问题。 The anti-forgery cookie token and form field token do not match in MVC 4

这可能是超时问题。基本上,当超时发生时,cookie不会被存储,因为运行该站点的iis用户没有正确的访问权限。对我来说,我更改了应用程序池以加载用户配置文件,这似乎解决了它。

答案 6 :(得分:0)

将@ Html.AntiForgeryToken()放入表单中

答案 7 :(得分:-1)

就我而言,这与IIS上的缓存有关。 我必须在服务器管理器中重新启动整个IIS服务器。