问题
here my problem,
I've got a rails 3.1 app and I'm trying to make an ajax request but I get the warning message "WARNING: Can't verify CSRF token authenticity"…
Inside my layout I've got the helper method "csrf_method_tag", and I add the following javascript code (don't know if it's really required or not):
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
My Gemfile contains the gem jquery-rails (>= 1.0.12) and I require jquery & jquery-ujs at the top of my application.js.
Even with that, the message still appears. Did i forget something?
Thanks for you help.
回答1:
What's worked for me - when working without forms - is to include the result of <%= form_authenticity_token %>
in the ajax data payload. So I do something like what was suggested by tehprofessor in the html:
<input id="tokentag" type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
then in the javascript:
tokentag = $('#tokentag').val()
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...}
then call the $.ajax
with submitdata
.
回答2:
I had this exact same trouble. I was trying to catch a javascript event (you_tube player completed) and Ajax back to my server to let me know. I was getting:
WARNING: Can't verify CSRF token authenticity
whenever the jQuery ajax call hit my server. I added your code fix above
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'));
}
});
and it works fine. I think the only difference is in my layout I have
<%= csrf_meta_tags %>
and not csrf_method_tag as you mentioned in your original post.
So thank you for the fix, it was in the original post.
回答3:
You probably don't even need this in your code. The jquery-rails
gem automatically sets the CSRF token on all Ajax requests by default.
回答4:
Just do it directly on your AJAX call and it will work right!
$.ajax({
type: //method,
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
url: //parameter,
dataType: 'html',
success: function(data, textStatus, jqXHR) {
// some code
}
});
回答5:
Have you tried using a hidden form element with authenticity token?
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token>" />
I was having the same error, and that resolved it. It was because I wasn't using the built in form helpers...
回答6:
One reason may be that you make AJAX call before document loaded, so JQuery can't get CSRF token.
回答7:
The problem is that you need to fetch a new token after an Ajax POST request because once a token is used it gets invalidated. Here is the code to do this:
In rails whenever a POST reply is sent add these parameters to the response:
def someMethod:
result[:csrfParam] = request_forgery_protection_token
result[:csrfToken] = form_authenticity_token
render :json => result
end
Now on the JS side, in the success function of every POST method you can call this function:
var setCsrfToken = function(param, token) {
if(param == null || token == null) {
console.error("New CSRF param/token not present");
}
$("input[name='" + param + "']").val(token);
}
like this:
setCsrfToken(result["csrfParam"], result["csrfToken"]);
This function will reset all authenticity_token params in all POST forms so that the next request has a valid token. You need to make sure this happens in every POST call, otherwise you'll continue facing this problem.
Also, CSRF is not for preventing clickjacking, it's a separate attack altogether, where another website can make a user click a link that executes an action on your website with the user's session.
来源:https://stackoverflow.com/questions/7270947/rails-3-1-csrf-ignored