rails: Rails 5.0.0beta3: form authenticity_token does not work when page loaded by Turbolinks
I have a simple Rails 5.0.0beta3 app with a simple form to create a record. Default configuration and environment in development.
<%= form_for @node, url: admin_book_nodes_url, as: :node do |form| %> <%= render “form”, f: form %>
<%= form.submit %> or <%= link_to "Cancel", admin_book_nodes_path %>
<% end %>
When the form is loaded through a link on another page of the app, on submission a ActionController::InvalidAuthenticityToken
is generated.
‘Started POST “/admin/book/nodes” for ::1 at 2016-03-20 11:54:31 +0000 Processing by Admin::Book::NodesController#create as HTML Parameters: {“utf8”=>“✓”, “authenticity_token”=>“/G5pF6hSPx0Vf21Fi0FCh+VlOcHY4w8C5lmHmwr3NQRjfXUP9/xboybeV3tevmyTyHcwSX8LplU/HgZVGDbGlw==”, “node”=>{“parent_id”=>“1”, “position”=>“1”, “title”=>“lkjlkj”, “description”=>“lkjlj”, “published”=>“0”, “content”=>“lkjlkj”}, “commit”=>“Create node”} Can’t verify CSRF token authenticity Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)’
However if the form page is manually reload before being filled then everything works fine. The behaviour is the same with both Safari and Chrome.
What I have noticed:
- When the form is loaded from a link on another page (failure case), it is loaded by Turbolinks through an XHR request. In such case the page authenticity token in
csrf_meta_tags
and the form’s token inauthenticity_token
have different values. - When the form is loaded or reloaded by the browser (successful case), so not by Turbolinks the tokens in in
csrf_meta_tags
and the form’sauthenticity_token
are the same.
Disabling Turbolinks specifically for the link to the form (e.g. <a data-turbolinks="false" href="/admin/book/nodes/new">New node</a>
) will also prevent the issue.
It does not seem the same as #23524, but perhaps it is related.
Note also my submission on Stackoverflow.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 2
- Comments: 29 (12 by maintainers)
Links to this issue
Commits related to this issue
- Discart the schema and host information when building the per-form token When the token is generated by the form we were using the schema and host information while only using the path to compare if ... — committed to rafaelfranca/omg-rails by rafaelfranca 8 years ago
- [Fix] ユーザーログイン機能 InvalidAuthenticityTokenの解消 https://github.com/rails/rails/issues/24257 https://stackoverflow.com/questions/36112939/rails-5-0-0beta3-actioncontrollerinvalidauthenticitytoken-in-dev... — committed to urotansh/term-app by urotansh a year ago
- [Fix] ユーザーログイン機能 InvalidAuthenticityTokenの解消 https://github.com/rails/rails/issues/24257 https://stackoverflow.com/questions/36112939/rails-5-0-0beta3-actioncontrollerinvalidauthenticitytoken-in-dev... — committed to urotansh/term-app by urotansh a year ago
- [Fix] ユーザーログイン機能 InvalidAuthenticityTokenの解消 https://github.com/rails/rails/issues/24257 https://stackoverflow.com/questions/36112939/rails-5-0-0beta3-actioncontrollerinvalidauthenticitytoken-in-dev... — committed to urotansh/term by urotansh a year ago
Using 5.0.1. Form is generate with <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
Still seeing this issue.
Should this be re-opened? Or are these reports of the issue still happening all false-alerts? (I’m seeing something similar as well (a form loaded with turbolinks throws InvalidAuthenticityToken error). (Rails 5.1.5)
I’ve the same issue:
:url
parameters and … ?What that damn hell RAILS is again doing … anyway, the workaround I found on my side (Do not ask me why), is to manually include an other token in the HTML form:
The two tokens will be send when submitting the form, the last one value will override the one crafted by the form helper and … it’s seem to works.
This happened to me even in a Rails 6 app. If someone is looking for a solution, this is what worked for me:
$(document).on('turbolinks:load', function(){ $.rails.refreshCSRFTokens(); });
You need
rails-ujs
orjquery-ujs
included with your app. If you’re on Rails 6 I believe you already haverails-ujs
by default.Also note https://github.com/plataformatec/devise/pull/4033/files
After further tinkering when trying to create a simple app reproducing the issue, it seems that the issue is related to the option
url
inform_for
(which I use in my app, see my initial submission).To reproduce (rails 5.0.0beta3, ruby 2.3.0p0):
The form must be accessed by following the link in the users’ index page.
Now, the above does work fine. But if the form’s code is changed to explicitly specify the URL of the ‘create’ action then a
ActionController::InvalidAuthenticityToken
is thrown when the form is submitted.For me this one worked https://github.com/rails/rails/issues/22965 “proxy_set_header X-Forwarded-Ssl on;”
It seems to be related to this issue https://github.com/heartcombo/devise/issues/5273 where the
rails dev:cache
appears to solve the invalid token case sometimes (including mine, which were two machines localy and a new setup on Windows/WSL+Ubuntu on this date for a new team member). I’m trying to figure out what the cache system really ‘solves’ 😄Any thoughts?
Cheers,
I honestly don’t know if my issue is related to this one or not. But its similar.
I am using partial react(partial in a sense that we are not using api but rails actionview and stuff in mix with react, it s migration in progress thats why) on
rails 5.1.4 and ruby 2.4.2
with turbolinks enabled.Issue we are facing is that **a page which is open for say a day and didn’t refresh, on that page there is a bulk delete button, which stops working and raises:
ActionController::InvalidAuthenticityToken
**(we suspect its because client does nto close the site and uses the same page after a day or two, because otherwise it is working all fine on dev and production)Of-course we have set
protect_from_forgery with: :exception
in application controller.While I prepare a reproduction app here’s the steps:
in the first fresh request I was able to extrapolate 2 csfr tokens from the page, one of which is in-form:
they appear to be the same and have been submitted successfully.
when I navigate to the form page again the tokens are different:
but when submitting this form a third, unknown token gets submitted instead:
which I verified not being in the page.
I noticed this error only shows up on FF for me, on Chrome it doesn’t throws any error. Is it possible that it has something to do with the browser?. Plus Turbolinks seems to be making two requests but again this only happens on FF and not on chrome.
Further testing has revealed it only occurs when passing an absolute URL to the
:url
option, not a relative path. In @elbartoloco’s example app, this works:But this produces the error: