I am sending data from view to controller with AJAXand I got this error:
WARNING: Can\'t verify CSRF token authenticity
I think
<%= csrf_meta_tag %>
in your layoutbeforeSend
to include the csrf-token in the ajax request to set the header. This is only required for post
requests.The code to read the csrf-token is available in the rails/jquery-ujs
, so imho it is easiest to just use that, as follows:
$.ajax({
url: url,
method: 'post',
beforeSend: $.rails.CSRFProtection,
data: {
// ...
}
})
If you are not using jQuery and using something like fetch API for requests you can use the following to get the 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)
})
The best way to do this is actually just use <%= form_authenticity_token.to_s %>
to print out the token directly in your rails code. You dont need to use javascript to search the dom for the csrf token as other posts mention. just add the headers option as below;
$.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) %>"
})
I struggled with this issue for days. Any GET call was working correctly, but all PUTs would generate a "Can't verify CSRF token authenticity" error. My website was working fine until I had added a SSL cert to nginx.
I finally stumbled on this missing line in my nginx settings:
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;
}
After adding the missing line "proxy_set_header X-Forwarded-Proto https;", all my CSRF token errors quit.
Hopefully this helps someone else who also is beating their head against a wall. haha
You should do this:
Make sure that you have <%= csrf_meta_tag %>
in your layout
Add beforeSend
to all the ajax request to set the header like below:
$.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);
}
});
To send token in all requests you can use:
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
The top voted answers here are correct but will not work if you are performing cross-domain requests because the session will not be available unless you explicitly tell jQuery to pass the session cookie. Here's how to do that:
$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
xhrFields: {
withCredentials: true
}
});