ActionController::InvalidAuthenticityToken when disable JS/Ajax request
Asked Answered
P

4

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?

Peter answered 18/10, 2013 at 15:1 Comment(3)
medBo, check if your form has csrf token inside in html output. If no, that may be the reason.Haught
@BillyChan there is no csrf token inside html of form ! i'm using rails 4 i think this is by design ? or what ?Peter
medBo, check my update.Haught
H
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.

Hepsibah answered 8/11, 2013 at 11:52 Comment(7)
yes @DanGarland exactly this is due to problem of fragment caching as the author in the the link above describe :)Peter
@DanGarland thanks. I had this issue with remote form which under certain conditions I dynamically convert to non-remote form by removing data-remote.Freshwater
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 endMurrah
I have the same problem of @JakeSmithKlinges
This is an old question but I'm getting the same error as Jake Smith and @Klinges -- did either of you find a solution?Mollie
A BIG thank you guy, we spent a lot of time investigating this strange behaviour in our app.Anastasiaanastasie
The same problem as @JakeSmith any solution?Hood
P
33

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.

Pantheism answered 18/6, 2014 at 11:16 Comment(1)
Nice explanation at 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....Semitrailer
O
5

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

 <%= csrf_meta_tags %>
Orion answered 29/5, 2016 at 13:38 Comment(0)
H
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.

Haught answered 18/10, 2013 at 15:32 Comment(1)
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 formPeter

© 2022 - 2024 — McMap. All rights reserved.