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

The required anti-forgery cookie "__RequestVerificationToken" is not present

我的网站每天大约出现 20 次此异常,通常表单工作正常,但有时会出现此问题,我不知道为什么如此随机。

这是 elmah 记录的异常

500 HttpAntiForgery The required anti-forgery cookie __RequestVerificationToken" is not present.

但是它发送令牌的形式如 elmahXML 日志中所示

<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>
}

这就是我 post 使用 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 上检查了其他问题,但对我没有任何作用。

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

此用于发送 SMS 的表单包含 ToNumber 和 Message 字段。当用户单击提交按钮时,AJAX 函数取得控制权并且 post 它序列化表单的字段数据,当我在控制器中的函数完成并且 return JSON 结果表示一切顺利,AJAX 方法重新加载页面,向用户显示一条成功消息。

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

听起来好像一切都在按预期进行。

防伪助手 @Html.AntiForgeryToken() 的工作方式是在页面中注入一个名为 __RequestVerificationToken 的隐藏表单字段,并且它还会在浏览器中设置一个 cookie。

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

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

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

另一方面,错误消息说相应的 COOKIE 没有被发送:

500 HttpAntiForgery The required anti-forgery cookie __RequestVerificationToken" is not present.

所以基本上 someone/something 是重播表单 post 而没有发出获取 cookie 的原始请求。因此他们有隐藏的表单字段 __RequestVerificationToken 但不是验证它的 cookie。

看来一切都在按预期进行。检查您的日志:IP 号码和引荐来源网址等。您可能受到攻击,或者在重定向表单内容时可能正在做一些奇怪或错误的事情。如上所述,假设没有被欺骗,referrers 是此类错误的良好起点。

另请注意,根据 MDN

location.reload();

The Location.reload() method reloads the resource from the current URL. Its optional unique parameter is a Boolean, which, when it is true, causes the page to always be reloaded from the server. If it is false or not specified, the browser may reload the page from its cache.

如果是,有时从缓存中加载,那么您最终可能会得到一个 POST 具有旧页面令牌但没有 cookie。

所以尝试:

location.reload(true);

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

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

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

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

  1. 服务器没有添加cookie请求,或者
  2. 浏览器拒绝了。

在我的例子中,是服务器:我没有在本地环境中使用 SSL,但在 web.config 中我有以下行:

<httpCookies requireSSL="True"/>

这种情况下的解决方案是切换到 SSL,或者将本地环境的值设置为 'False'。

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

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

按照说明解决问题:

转到设置 > 查看高级设置 > Cookies > 更改为 "Don't block cookies"。

关闭浏览器并检查。

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

检查您是否在前端@Html.AntiForgeryToken() 中遗漏了这一行

在我的例子中,它与 IIS 上的缓存有关。 我不得不在服务器管理器中重新启动整个 IIS 服务器。

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