所需的防伪cookie"__RequestVerificationToken"不存在 [英] The required anti-forgery cookie "__RequestVerificationToken" is not present

查看:771
本文介绍了所需的防伪cookie"__RequestVerificationToken"不存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的网站每天大约发出20次此异常,通常该表单可以正常工作,但在某些情况下会出现此问题,我不知道为什么如此随机.

My website is raising this exception around 20 times a day, usually the form works fine but there are instances where this issue occur and I don't know why is so random.

这是Elmah记录的异常

This is logged exception by elmah

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

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

但是它发送的形式是令牌,如elmah在XML日志中所示

But the form it is sending the the token as shown on the XML log by elmah

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

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

This is my method on the controller which uses the data Attribute to check if the token is valid or nor

[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发布数据

And this how I post my data using 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上检查了其他问题,但对我没有任何帮助.

The form works well most time but this error keeps happening and I don't know why, I've checked other questions here on Stack Overflow but nothing works for me.

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

For further explanation about how I post the data.

此发送SMS的表单具有ToNumber和Message字段.当用户单击提交"按钮时,AJAX函数将控制并发布它以序列化表单的字段数据,当我在控制器中的函数完成并返回表示一切顺利的JSON结果时,AJAX方法将重新加载该页面,向用户显示成功消息.

This form to send SMS has the fields ToNumber and Message. When a user clicks on the submit Button the AJAX function takes control and post it serializing the form's field data, when my function in the controller finishes and return the JSON result indicating everything went well, the AJAX method reloads the page showing the user a success message.

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

Any ideas what could be causing this issue.

推荐答案

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

It almost sounds as if things are working as expected.

反伪造助手@Html.AntiForgeryToken()的工作方式是在页面中注入一个名为__RequestVerificationToken的隐藏表单域,并且还将cookie设置到浏览器中.

The way the anti forgery helper @Html.AntiForgeryToken() works is by injecting a hidden form field named __RequestVerificationToken into the page AND it also sets a cookie into the browser.

将表单发回时,将两者进行比较,如果它们不匹配或缺少cookie,则会引发错误.

When the form is posted back the two are compared and if they don't match or the cookie is missing then the error is thrown.

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

So it does not matter that Elmah logs that the form is sending __RequestVerificationToken. It always will, even in the event of CSRF attack, because this is simply the hidden form field.

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

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

The error message on the other hand says the corresponding COOKIE is not being sent:

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

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

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

So basically someone/something is replaying the form post without making the original request to get the cookie. As such they have the hidden form field __RequestVerificationToken but NOT the cookie to verify it.

因此,看来事情正在按预期进行.请重新检查您的日志:IP号和引荐来源网址等.在重定向表单内容时,您可能受到攻击,或者正在做某些奇怪或错误的事情.如上所述,假设没有被欺骗,referrers是开始处理此类错误的好地方.

So it seems like things are working as they should. Check your logs re: IP numbers, and referrers, etc. You might be under attack or perhaps be doing something weird or buggy when redirecting your form content. As above, referrers are a good place to start for this kind of error, assuming this is not being spoofed.

还要注意,按照 MDN

Also note that as per MDN

location.reload();

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

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.

If it is, on occasion loading from cache, then you might end up with a POST that has the old page token but not the cookie.

所以尝试:

location.reload(true);

这篇关于所需的防伪cookie"__RequestVerificationToken"不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆