web-dev-qa-db-fra.com

Comment faire une demande Ajax avec un jeton anti-contrefaçon dans MVC

J'ai un problème avec les détails ci-dessous du projet MVC.

Lorsque j'essaie d'utiliser la demande jquery ajax avec le panneau de chargement comme le spin gif (ou même du texte), je reçois une erreur, observée par le violoniste qui

Le champ de formulaire anti-contrefaçon obligatoire "__RequestVerificationToken" n'est pas présent.

Si je commente [ValidateAntiForgeryToken] attribute at POST et utilisation du panneau de chargement, cela fonctionne bien. Je veux savoir pourquoi j'obtiens cette erreur.

J'ai même utilisé la chaîne de requête sérialisée avec

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

je reçois toujours une erreur

Le jeton anti-contrefaçon n'a pas pu être déchiffré. Si cette application est hébergée par une batterie de serveurs ou un cluster Web, assurez-vous que toutes les machines exécutent la même version des pages Web ASP.NET et que le <machineKey> la configuration spécifie des clés de chiffrement et de validation explicites.

AutoGenerate ne peut pas être utilisé dans un cluster

Que dois-je utiliser?

Ici, il a mis à jour le code de question

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

        });
    }
});

balises de formulaire

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

Balise de formulaire TransportJob 2 sur la même page

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

Avez-vous ajouté votre jeton à l'en-tête de l'appel ajax?

Vous devez ajouter AntiForgeryToken dans votre en-tête de message lors de l'appel ajax:

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

var headers = {};

headers['__RequestVerificationToken'] = token;

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

Essayez ceci dans votre code:

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

        });
    }
});

Ligne d'en-têtes ajoutée dans votre appel ajax.

18
freshbm

Plutôt que de l'ajouter manuellement à chaque demande, je fais généralement quelque chose comme ceci:

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

Cela ajoutera automatiquement votre jeton à n'importe lequel ajax POST vous le faites.

34
Kippie

Avez-vous ajouté le jeton à votre vue? Comme ça:

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

Étant donné que votre contrôleur recevant le message recherche le jeton anti contrefaçon, vous devez vous assurer de l'ajouter à votre formulaire dans la vue.

MODIFIER:

Essayez d'abord de créer vos données dans json:

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

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

Affichage ou mise en page:

<form id = '_ id' method = 'POST'> @ html.antiforgeryToken (); </ formulaire>

La fonction d'appel ajax:

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

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

Je voulais sécuriser à la fois Ajax et la demande normale, alors voici ce que j'ai sorti:

En utilisant d'abord l'excellent blog de haacked.com J'ai créé le ConditionalFilterProvider comme décrit.

Ensuite, j'ai créé toutes les classes comme décrit sur le blog de codethinked .

Sur ma page _layout, j'ai ajouté le morceau avec le $ .ajaxPrefilter comme décrit dans le blog ... Cela garantit que tous mes rappels Ajax envoient maintenant le jeton Antiforgery via l'en-tête.

Pour coller tous ensemble, j'ai ajouté ce morceau de code sur mon 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

Fondamentalement ... injectez l'attribut à tous mes contrôleurs qui ne sont pas GET.

Après cela, je devais simplement aller à tous mes (très peu) formulaires et ajouter le @ Html.AntiForgeryToken ().

Pour prouver que tout a fonctionné, j'essaie simplement de densifier les choses avec un formulaire sans AntiForgeryToken et d'obtenir l'exception attendue. Et supprimez le $ .ajaxPrefilter et créez des demandes Ajax et l'exception attendue a été reçue.

0
CodeHacker