Подтвердить что ты не робот

Необходимого анти-подделки cookie "__RequestVerificationToken" нет

Мой сайт поднимает это исключение примерно 20 раз в день, обычно форма работает нормально, но есть случаи, когда эта проблема возникает, и я не знаю, почему это так.

Это исключение из журнала elmah

500 HttpAntiForgery Требуемый анти-подделки cookie __RequestVerificationToken "нет.

Но форма отправляет токен, как показано в XML-журнале, 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>

Это мой метод на контроллере, который использует атрибут данных, чтобы проверить, действительно ли токен, или

[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, но ничего не работает для меня.

Для дальнейшего объяснения того, как я публикую данные.

В этой форме для отправки SMS есть поля ToNumber и Message. Когда пользователь нажимает кнопку отправки, функция AJAX берет на себя управление и публикует сериализацию данных поля формы, когда моя функция в контроллере заканчивается и возвращает результат JSON, указывающий на то, что все прошло хорошо, метод AJAX перезагружает страницу, показывающую пользователю успех сообщение.

Любые идеи, которые могут вызвать эту проблему.

4b9b3361

Ответ 1

Похоже, что все работает так, как ожидалось.

Как работает вспомогательный помощник @Html.AntiForgeryToken(), путем ввода в страницу скрытого поля формы с именем __RequestVerificationToken И он также устанавливает cookie в браузер.

Когда форма отправляется обратно, эти два сравниваются, и если они не совпадают или файл cookie отсутствует, возникает ошибка.

Поэтому не имеет значения, что Elmah регистрирует, что форма отправляет __RequestVerificationToken. Это всегда будет, даже в случае атаки CSRF, потому что это просто скрытое поле формы.

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

Сообщение об ошибке, с другой стороны, говорит, что соответствующий COOKIE не отправляется:

500 HttpAntiForgery Необходимый файл анти-подделки __RequestVerificationToken "нет.

Таким образом, в основном кто-то/что-то переигрывает сообщение формы, не делая первоначальный запрос на получение файла cookie. Таким образом, они имеют скрытое поле формы __RequestVerificationToken, но не файл cookie, чтобы проверить его.

Итак, похоже, что все работает так, как должно. Проверьте свои журналы: IP-номера и источники ресурсов и т.д. Возможно, вы подверглись атаке или, возможно, сделали что-то странное или ошибочное при перенаправлении содержимого своей формы. Как и выше, referrers - хорошее место для начала такого рода ошибок, предполагая, что это не подделка.

Также обратите внимание, что согласно MDN

location.reload();

Метод Location.reload() перезагружает ресурс из текущего URL. Его необязательный уникальный параметр - логический, который, когда он true, заставляет страницу всегда перезагружаться с сервера. Если это false или не указано, браузер может перезагрузить страницу из своего Кэш.

Если это так, иногда загружаясь из кеша, вы можете получить POST, у которого есть старый токен страницы, но не файл cookie.

Итак, попробуйте:

location.reload(true);

Ответ 2

В последнее время появилась аналогичная проблема. Анти-подделки cookie действительно отсутствовали, поэтому (как указывали другие) либо

  • сервер не добавил cookie для запроса или
  • браузер отклонил его.

В моем случае это был сервер: я не использовал SSL в локальной среде, но в web.config у меня была следующая строка:

<httpCookies requireSSL="True"/>

Решение в этом случае - либо переключиться на SSL, либо сохранить значение "False" для локальной среды.

Ответ 3

В дополнение к превосходному ответу Rism, еще одна возможная причина столкновения с этой ошибкой заключается в том, что ваш браузер или плагин браузера блокирует файлы cookie.

Ответ 4

У меня была такая же проблема в пограничном браузере.

Я исправил эту проблему, изменив настройки браузера.

Следуйте инструкциям, чтобы решить проблему:

Выберите "Настройки"> "Просмотр дополнительных настроек"> "Файлы cookie"> "Не блокировать файлы cookie".

Закройте браузер и проверьте.

Я думал, это может кому-то помочь.

Ответ 5

проверьте, пропустили ли вы эту строку в своем интерфейсе @Html.AntiForgeryToken() или нет

Ответ 6

Можете взглянуть на этот вопрос. Символ маркера анти-подделки и маркер поля формы не совпадают в MVC 4

Возможно, это проблема с таймаутом. В основном, когда происходит тайм-аут, cookie не сохраняется, поскольку пользователь iis, на котором работает сайт, не имеет надлежащего доступа. Для меня я изменил пул приложений, чтобы загрузить профиль пользователя, и это, казалось, исправить.