44

I have two forms with option remote: true; one sends an Ajax request to create action and the other one sends an Ajax request to destroy action.

All work fines when JavaScript is enabled, but if I disable JavaScript, then I click, I get this error:

ActionController::InvalidAuthenticityToken PersonsController#create

Why this error is shown, and how can I fix it ?

note: I'm using Rails 4

Update

When I use a normal form without option remote: true, rails automatically inserts a hidden field for an authentication token, but when I use remote: true in my form there is no such field in the HTML code. It seems like when there is remote option, then Rails handles the authentication token differently, so how I can get this to work in both cases?

Community
  • 1
  • 1
medBouzid
  • 7,484
  • 10
  • 56
  • 86

4 Answers4

122

Bizarrely, this behaviour was changed in rails 4. http://www.alfajango.com/blog/rails-4-whats-new/

Rails forms now will not render the CSRF field in the form unless you explicitly define it as an option to your form:

<%= form_for @some_model, :remote => true, :authenticity_token => true do |f| %>
<% end %>

Adding this option allows you to gracefully degrade to a HTML fallback if Javascript is switched off.

Dan Garland
  • 3,350
  • 1
  • 24
  • 24
  • yes @DanGarland exactly this is due to problem of fragment caching as the author in the the link above describe :) – medBouzid Nov 08 '13 at 12:37
  • @DanGarland thanks. I had this issue with remote form which under certain conditions I dynamically convert to non-remote form by removing data-remote. – Slobodan Kovacevic Feb 27 '14 at 21:04
  • 3
    as soon as I added `authenticity_token: true` to the `bootstrap_form_for` call, I get an `UnknownFormat` error, meaning the `remote: true` is no longer being recognized. Previously, I did not have the `authenticity_token: true` on the form and received the error message that led me to this post. Would you know why adding the `authenticity_token: true` to the `bootstrap_form_for` would cause the `remote: true` to stop working? The form has the `data-remote="true"` in the html, so I'm not sure what the issue is here: `UnknownFormat` pointing to my `repond_to do |format| format.js end` – Jake Smith Mar 19 '14 at 17:40
  • I have the same problem of @JakeSmith – rizidoro May 09 '14 at 23:07
  • This is an old question but I'm getting the same error as Jake Smith and @rizidoro -- did either of you find a solution? – SataGNUk Nov 12 '14 at 14:42
  • A BIG thank you guy, we spent a lot of time investigating this strange behaviour in our app. – Andrea Salicetti Oct 06 '15 at 08:30
  • The same problem as @JakeSmith any solution? – ascherman Oct 14 '16 at 14:14
32

Me too faced the same problem. I have used form_tag to create custom remote form, but i got the the following error,

 ActionController::InvalidAuthenticityToken

I found that this is because in rail 4 wont add authenticity toke by default, so i added the following line in application.rb file,

 config.action_view.embed_authenticity_token_in_remote_forms = true

which automatically verify the toke when submitting the remote forms. This solves the problem for me. Hope this will help some one.

Abhiram
  • 1,459
  • 14
  • 23
  • 7
    Nice explanation at http://edgeguides.rubyonrails.org/configuring.html: `config.action_view.embed_authenticity_token_in_remote_forms` allows you to set the default behavior for authenticity_token in forms with :remote => true. By default it's set to false, which means that remote forms will not include authenticity_token, which is helpful when you're fragment-caching the form. Remote forms get the authenticity from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.... – bigtex777 Apr 16 '15 at 01:33
5

In my case i just had to add this line in my page:

 <%= csrf_meta_tags %>
Ivan Chernykh
  • 41,617
  • 13
  • 134
  • 146
0

If there is no csrf field(a hidden field) inside the form, the submission can't be authenticated by Rails server.

If you make the form by form_tag, this situation will happen. The better approach is to use form_for for a resource(new object or an existing object in db) and csrf field will be built by Rails automatically.

Billy Chan
  • 24,625
  • 4
  • 52
  • 68
  • 2
    hi @BillyChan my problem isn't with ajax request, i use already remote: true and it works fine, my problem is when i disable javascript and i try to submit the form such as normal form – medBouzid Oct 18 '13 at 15:52