所需的防伪cookie"__RequestVerificationToken"不存在

Gen*_*ric 27 c# cookies asp.net-mvc jquery 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>
Run Code Online (Sandbox Code Playgroud)

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

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

这是我在视图上的表单

@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>
}
Run Code Online (Sandbox Code Playgroud)

这就是我如何使用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;
});
Run Code Online (Sandbox Code Playgroud)

表单在大多数时间运行良好,但这个错误一直在发生,我不知道为什么,我已经在Stack Overflow上检查了其他问题,但对我来说没有任何作用.

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

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

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

ris*_*ism 24

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

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

回传表单时,将比较两个表单,如果它们不匹配或cookie丢失,则抛出错误.

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

<input name="__RequestVerificationToken" type="hidden" value="DNbDMrzHmy37GPS6IFH-EmcIh4fJ2laezIrIEev5f4vOhsY9T7SkH9-1b7GPjm92CTFtb4dGqSe2SSYrlWSNEQG1MUlNyiLP1wtYli8bIh41" />
Run Code Online (Sandbox Code Playgroud)

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

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

因此,基本上某人/某事正在重播表单帖子,而没有提出获取cookie的原始请求.因此,他们有隐藏的表单字段, __RequestVerificationToken但不是用于验证它的cookie.

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

另请注意,根据MDN

location.reload();
Run Code Online (Sandbox Code Playgroud)

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

如果是,有时从缓存加载,那么你最终可能会得到一个POST具有旧页面令牌而不是cookie的cookie.

所以尝试:

location.reload(true);
Run Code Online (Sandbox Code Playgroud)


Rod*_*kyi 16

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

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

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

<httpCookies requireSSL="True"/>
Run Code Online (Sandbox Code Playgroud)

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

  • 在我们的例子中,我们遇到了在localhost项目之间切换的问题,其中一些*是*SSL而一些*不是*SSL (3认同)

Sam*_*iew 8

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