J'envoie des données de la vue au contrôleur avec AJAX et j'ai cette erreur:
AVERTISSEMENT: impossible de vérifier l'authenticité du jeton CSRF
Je pense que je dois envoyer ce jeton avec des données.
Est-ce que quelqu'un sait comment puis-je faire cela?
Edit: Ma solution
Je l'ai fait en mettant le code suivant dans le message AJAX:
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
Vous devriez faire ceci:
Assurez-vous que vous avez <%= csrf_meta_tag %>
dans votre mise en page
Ajoutez beforeSend
à toute la requête ajax pour définir l'en-tête comme ci-dessous:
$.ajax({ url: 'YOUR URL HERE',
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
data: 'someData=' + someData,
success: function(response) {
$('#someDiv').html(response);
}
});
Pour envoyer un jeton dans toutes les demandes, vous pouvez utiliser:
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
La meilleure façon de faire est d’utiliser <%= form_authenticity_token.to_s %>
pour imprimer le jeton directement dans votre code Rails. Vous n’avez pas besoin d’utiliser javascript pour rechercher le jeton csrf dans le dom comme le mentionnent d’autres publications. il suffit d’ajouter l’option en-têtes ci-dessous;
$.ajax({
type: 'post',
data: $(this).sortable('serialize'),
headers: {
'X-CSRF-Token': '<%= form_authenticity_token.to_s %>'
},
complete: function(request){},
url: "<%= sort_widget_images_path(@widget) %>"
})
Si je me souviens bien, vous devez ajouter le code suivant à votre formulaire pour résoudre ce problème:
<%= token_tag(nil) %>
N'oubliez pas le paramètre.
En effet, le moyen le plus simple. Ne vous embêtez pas pour changer les en-têtes.
Assurez-vous que vous avez:
<%= csrf_meta_tag %> in your layouts/application.html.erb
Il suffit de faire un champ de saisie caché comme ceci:
<input name="authenticity_token"
type="hidden"
value="<%= form_authenticity_token %>"/>
Ou si vous voulez un post jQuery ajax:
$.ajax({
type: 'POST',
url: "<%= someregistration_path %>",
data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },
error: function( xhr ){
alert("ERROR ON SUBMIT");
},
success: function( data ){
//data response can contain what we want here...
console.log("SUCCESS, data="+data);
}
});
La mise à niveau d'une ancienne application vers Rails 3.1, y compris la balise méta csrf, ne résout toujours pas le problème. Sur le blog de rubyonrails.org, ils donnent quelques conseils de mise à niveau, et plus particulièrement cette ligne de requête qui devrait figurer dans la section head de votre mise en page:
$(document).ajaxSend(function(e, xhr, options) {
var token = $("meta[name='csrf-token']").attr("content");
xhr.setRequestHeader("X-CSRF-Token", token);
});
extrait de cet article de blog: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-Ruby-on-Rails .
Dans mon cas, la session était réinitialisée à chaque demande ajax. L'ajout du code ci-dessus a résolu ce problème.
<%= csrf_meta_tag %>
dans votre mise en pagebeforeSend
pour inclure le jeton csrf dans la demande ajax afin de définir l'en-tête. Ceci n'est requis que pour les requêtes post
.Le code pour lire le jeton csrf est disponible dans le Rails/jquery-ujs
, alors il est plus simple de l'utiliser, comme suit:
$.ajax({
url: url,
method: 'post',
beforeSend: $.Rails.CSRFProtection,
data: {
// ...
}
})
Je pensais juste que je ferais un lien ici car l'article contient l'essentiel de la réponse que vous recherchez et qu'il est également très intéressant.
Les réponses les plus votées ici sont correctes mais ne fonctionneront pas si vous effectuez des requêtes inter-domaines car la session ne sera pas disponible, sauf si vous indiquez explicitement à jQuery de transmettre le cookie de session. Voici comment faire cela:
$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
xhrFields: {
withCredentials: true
}
});
Vous pouvez l'écrire globalement comme ci-dessous.
JS normal:
$(function(){
$('#loader').hide()
$(document).ajaxStart(function() {
$('#loader').show();
})
$(document).ajaxError(function() {
alert("Something went wrong...")
$('#loader').hide();
})
$(document).ajaxStop(function() {
$('#loader').hide();
});
$.ajaxSetup({
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
});
});
Café Script:
$('#loader').hide()
$(document).ajaxStart ->
$('#loader').show()
$(document).ajaxError ->
alert("Something went wrong...")
$('#loader').hide()
$(document).ajaxStop ->
$('#loader').hide()
$.ajaxSetup {
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
}
oops..
J'ai raté la ligne suivante dans mon application.js
//= require jquery_ujs
Je l'ai remplacé et ça marche ..
======= UPDATED ==========
Après 5 ans, je suis de retour avec la même erreur, maintenant j'ai tout nouveau Rails 5.1.6 , et j'ai retrouvé ce message. Tout comme le cercle de la vie.
Maintenant quel était le problème: Rails 5.1 supprimait la prise en charge de jquery et jquery_ujs par défaut et ajouté
//= require Rails-ujs in application.js
Il fait les choses suivantes:
Mais pourquoi n'inclut-il pas le jeton csrf pour la demande ajax? Si quelqu'un sait à ce sujet en détail, n'hésitez pas à me commenter. J'apprécie ça.
Quoi qu'il en soit, j'ai ajouté ce qui suit dans mon fichier js personnalisé pour le faire fonctionner (Merci pour d'autres réponses pour m'aider à atteindre ce code):
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': Rails.csrfToken()
}
});
----
----
});
Utilisez jquery.csrf ( https://github.com/swordray/jquery.csrf ).
Rails 5.1 ou plus tard
$ yarn add jquery.csrf
//= require jquery.csrf
Rails 5.0 ou avant
source 'https://Rails-assets.org' do
gem 'Rails-assets-jquery.csrf'
end
//= require jquery.csrf
Code source
(function($) {
$(document).ajaxSend(function(e, xhr, options) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
});
})(jQuery);
Si vous n'utilisez pas jQuery et utilisez quelque chose comme fetch API pour les demandes, vous pouvez utiliser ce qui suit pour obtenir le csrf-token
:
document.querySelector('meta[name="csrf-token"]').getAttribute('content')
fetch('/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')},
credentials: 'same-Origin',
body: JSON.stringify( { id: 1, name: 'some user' } )
})
.then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('request failed', error)
})
Si vous utilisez javascript avec jQuery pour générer le jeton dans votre formulaire, cela fonctionne:
<input name="authenticity_token"
type="hidden"
value="<%= $('meta[name=csrf-token]').attr('content') %>" />
Évidemment, vous devez avoir le <%= csrf_meta_tag %>
dans votre layout Ruby.
Pour ceux d'entre vous qui ont besoin d'une réponse non jQuery, vous pouvez simplement ajouter les éléments suivants:
xmlhttp.setRequestHeader ('X-CSRF-Token', $ ('meta [nom = "csrf-token"] "). attr (" contenu "));
Voici un exemple très simple:
xmlhttp.open ("POST", "example.html", true); xmlhttp.setRequestHeader ('X-CSRF-Token', $ ('méta [nom = "csrf-token "] '). attr (' contenu ')); xmlhttp.send ();
si quelqu'un a besoin d'aide concernant Uploadify et Rails 3.2 (comme moi quand j'ai googlé ce post), cet exemple d'application peut être utile: https://github.com/n0ne/Uploadify-Carrierwave -Rails-3.2.3/blob/master/app/vues/images/index.html.erb
vérifiez également la solution de contrôleur dans cette application
J'ai lutté avec ce problème pendant des jours. Tout appel GET fonctionnait correctement, mais tous les PUT généraient l'erreur "Impossible de vérifier l'authenticité du jeton CSRF". Mon site Web fonctionnait bien jusqu'à ce que j'ajoute un certificat SSL à nginx.
Je suis finalement tombé sur cette ligne manquante dans mes paramètres nginx:
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_Host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto https; # Needed to avoid 'WARNING: Can't verify CSRF token authenticity'
proxy_pass http://puma;
}
Après avoir ajouté la ligne manquante "proxy_set_header X-Forwarded-Proto https;", toutes mes erreurs de jeton CSRF se sont arrêtées.
J'espère que cela aidera quelqu'un d'autre qui se frappe aussi la tête contre un mur. haha
J'utilise Rails 4.2.4 et je ne peux pas comprendre pourquoi je reçois:
Can't verify CSRF token authenticity
J'ai dans la mise en page:
<%= csrf_meta_tags %>
Dans le contrôleur:
protect_from_forgery with: :exception
Invoquer tcpdump -A -s 999 -i lo port 3000
montrait que l'en-tête était en train d'être défini (même s'il n'était pas nécessaire de définir les en-têtes avec ajaxSetup
- cela avait déjà été fait):
X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
DNT: 1
Content-Length: 125
authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
À la fin, c’était un échec car j’avais éteint les cookies. CSRF ne fonctionne pas sans l'activation des cookies, c'est donc une autre cause possible si vous voyez cette erreur.