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

Как сделать запрос ajax с токеном анти-подделки в mvc

У меня проблема с деталями ниже из проекта MVC.

Когда я пытаюсь использовать jquery-запрос ajax с панелью загрузки, например, spinning gif (или даже текст), я получаю ошибку, наблюдаемую у скрипача, который

Требуемое поле формы для защиты от подделки "__RequestVerificationToken" отсутствует.

Если я прокомментирую   [ValidateAntiForgeryToken] attribute при методе действия POST и используйте панель загрузки, она работает нормально. Я хочу знать, почему я получаю эту ошибку.

Я даже использовал строку запроса, сериализованную с помощью

__RequestVerificationToken= $('input[name="__RequestVerificationToken"').val()

все еще я получаю ошибку

Запрет на подделку не может быть расшифрован. Если это приложение размещено веб-фермой или кластером, убедитесь, что на всех компьютерах установлена ​​одна и та же версия веб-страниц ASP.NET, а в конфигурации <machineKey> указаны явные ключи шифрования и проверки.

Автогенерация не может использоваться в кластере

Что я должен использовать?

Здесь он обновил код вопроса

var token = $('input[name="__RequestVerificationToken"]').val();
$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //}, 
             data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

формы тегов

<form action="/TransportJob/Create" method="post"><input     name="__RequestVerificationToken" type="hidden"   value="ydYSei0_RfyBf619dQrhDwwoCM7OwWkJQQEMNvNdAkefiFfYvRQ0MJYYu0zkktNxlJk_y1ZJO9-yb-  COap8mqd0cvh8cDYYik4HJ0pZXTgE1" />   

      TransportJob form tag 2 на той же странице

<form action="/TransportJobAddress/Create" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden"    value="Np2vUZJPk1TJlv846oPSU6hg4SjMHRcCk1CacaqZbpHOg8WbV4GZv06noRDl7F_iT9qQf3BIXo3n9wGW68sU mki7g3-ku_BSHBDN-g2aaKc1"> 

4b9b3361

Ответ 1

Добавили ли вы токен в заголовок вызова ajax?

Вам нужно добавить AntiForgeryToken в свой заголовок сообщения в вызове ajax:

var token = $('input[name="__RequestVerificationToken"]').val();

var headers = {};

headers['__RequestVerificationToken'] = token;

$.ajax({
        url: ... some url,
        headers: headers,
        ....
});

Попробуйте это в своем коде:

var token = $('input[name="__RequestVerificationToken"]').val();
var tokenadr = $('form[action="/TransportJobAddress/Create"] input[name="__RequestVerificationToken"]').val(); 

var headers = {};
var headersadr = {};
headers['__RequestVerificationToken'] = token;
headersadr['__RequestVerificationToken'] = tokenadr;

$('#submitaddress').click(function subaddr(event) {
    event.preventDefault();
    event.stopPropagation();
  //$('#addAddress').html('<img src="/img/animated-overlay.gif"> Sending...');
   // $('#addAddress').blur();
    //  $(this).bl
    if ($('#Jobid').val()!="") {
        $('#TransportJobId').val(parseInt($('#Jobid').val()));
        $.ajax(
              {
                  url: '/TransportJobAddress/create',
                  type: 'POST',
                  headers:headersadr, 
                  data: "__RequestVerificationToken=" + token + "" + $('form[action="/TransportJobAddress/Create"]').serialize(),
                  success: function poste(data, textStatus, jqXHR) { $('#addAddress').html(data); return false; },
                  error: function err(jqXHR, textStatus, errorThrown) { alert('error at address :' + errorThrown); }
              });
    }
    else {
        var transportid = 2;
        $.ajax({
            url: '/TransportJob/create',
            type: 'POST',
            headers:headers, 
            data: $('form[action="/TransportJob/Create"]').serialize(),
            success: function sfn(data, textStatus, jqXHR) {
                transportid = parseInt(data);
                $('#Jobid').val(data);
               // alert('inserted id :' + data);
                $('#TransportJobId').val((transportid));
                $.ajax(
         {

             url: '/TransportJobAddress/create',
             type: 'POST',
             //beforeSend: function myintserver(xhr){  
             //        $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
             //},
             headers:headers, 
             data: $('form[action="/TransportJobAddress/Create"]').serialize(),
             success: function poste(data, textStatus, jqXHR) {
                 $('#addAddress').html(data);

             },
             error: function err(jqXHR, textStatus, errorThrown) {
                 alert('error at address :' + errorThrown);
             }

         });
            },
            error: function myfunction(jqXHR, textStatus, errorThrown) {
                alert("error at transport :" + jqXHR.textStatus);
            },
            complete: function completefunc() {
              //  alert('ajax completed all requests');
                return false;
            }

        });
    }
});

Добавлена ​​строка заголовков в вашем вызове ajax.

Ответ 2

Вместо того, чтобы вручную добавлять его к каждому запросу, я обычно делаю что-то вроде этого:

var token = $('input[name="__RequestVerificationToken"]').val();
$.ajaxPrefilter(function (options, originalOptions) {
  if (options.type.toUpperCase() == "POST") {
    options.data = $.param($.extend(originalOptions.data, { __RequestVerificationToken: token }));
  }
});

Это автоматически добавит ваш токен к любому POST-сообщению ajax.

Ответ 3

Добавили ли вы токен в свой вид? Вот так:

<form method="post" action="/my-controller/my-action">
    @Html.AntiForgeryToken()
</form>

Поскольку ваш контроллер, получающий сообщение, ищет токен анти-подделки, вам нужно убедиться, что вы добавили его в свою форму в виде.

EDIT:

Сначала создайте свои данные в json:

var formData = $('form[action="/TransportJobAddress/Create"]').serialize();
$.extend(formData, {'__RequestVerificationToken': token });

//and then in your ajax call:
$.ajax({
    //...
    data:formData
    //...
});

Ответ 4

Вид или макет:

< form id = '_ id' method = 'POST' > @html.antiforgeryToken(); </Формa >

Функция вызова ajax:

var data={...};
var token=$('#_id').serializeObject();
var dataWithAntiforgeryToken = $.extend(data,token);

$.ajax(
{
....,
data: dataWithAntiforgeryToken;
}
)

Ответ 5

Я хотел защитить оба Ajax и обычный запрос, поэтому вот что я получил:

Сначала используйте отличный блог из haacked.com я Создал ConditionalFilterProvider, как описано.

Затем я создал все классы, как описано в блоге, из codethinked.

На моей странице _layout я добавил часть с $.ajaxPrefilter, как описано в блоге... Это гарантирует, что все мои Ajax-обратные вызовы теперь отправляют токен Antiforgery через заголовок.

Чтобы склеить все вместе, я добавил этот фрагмент кода в свой файл global.asax/Application_Start

(c, a) =>
                    (c.HttpContext.Request.IsAjaxRequest() &&
                     !string.Equals(c.HttpContext.Request.HttpMethod, "GET"))
                        ? new AjaxValidateAntiForgeryTokenAttribute()
                        : null,
(c, a) =>
                    (!c.HttpContext.Request.IsAjaxRequest() &&
                     string.Equals(c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase))
                        ? new ValidateAntiForgeryTokenAttribute()
                        : null

В принципе.. вставляйте атрибут ко всем моим контроллерам, которые не являются GET.

После этого мне просто нужно было пройти все мои (очень немногие) формы и добавить @Html.AntiForgeryToken().

Чтобы доказать, что все сработало, я просто пытаюсь записать вещи с помощью формы без AntiForgeryToken и получить ожидаемое исключение. И удалите $.ajaxPrefilter и создайте Ajax-запросы, и ожидаемое исключение было получено.