I have some javascript making an ajax call in my Rails site:
$.ajax({type: "PUT", url: url, data: { dummy: data }, complete: function(data) {}});
When Rails gets it, it throws back an ActionController::InvalidAuthenticityToken
Error. I'd like to keep the protect_from_forgery stuff in there, if possible... But I'm at a loss for how can I pass the auth token from a javascript file?
Can anyone help me out?
In your layout, add this before any other JS runs:
<script>
function authToken() {
return '<%= form_authenticity_token if protect_against_forgery? -%>';
}
</script>
authToken
is coded as a function so that it's less likely you'll accidentally overwrite it with other JavaScript.
Alternatively, as of Rails 3, the auth token is embedded as a <meta>
tag, which you can read with:
<script>
function authToken() {
return $('meta[name="csrf-token"]').attr('content');
}
</script>
In your main JS, you can then call authToken()
, and it'll return your authenticity token as a string to include in your Ajax calls. For example, using jQuery:
$.ajax({
type: 'PUT',
url: url,
data: {
foo: bar,
authenticity_token: authToken()
},
complete: function(data) {}
});
Note that if you use Rails' built-in form_for
helper, it automatically adds the authenticity token in a hidden input. If you want to send all of the form's data, including the hidden auth token, you can simply use:
var $form = $('form');
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
// "get" or "post"; overridden by Rails' hidden "_method"
// input value, e.g., "put"
data: $form.serialize(),
// Includes hidden "authenticity_token" and "_method" inputs
complete: function(data) {}
});
This pattern is often useful when you've already written a form that works without JS, and you're adding an unobtrusive layer of JS that simply sends the form's data via Ajax.
Thanks for the above solution.
I am using some standard forms in my site that don't use the rails form_tag so instead I simply added it as a hidden form element.
<form action="...">
<%= hidden_field_tag 'authenticity_token', form_authenticity_token if protect_against_forgery? %>
... rest of form...
</form>
Works a treat.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With