ruby-on-railscsrf-protectionactioncontrollerruby-on-rails-5

Rails 5.0.0beta3: ActionController::InvalidAuthenticityToken in development


I have just started a simple app with a couple of forms on Rails 5.0.0beta3.

In development, using http://localhost:3000 on Safari or Chrome to access the app, if I fill a form and submit it I always get an ActionController::InvalidAuthenticityToken error. However, if I reload the page before filling and submitting it then it works fine.

The app uses the defaults:

Example:

<%= form_for @node, url: admin_book_nodes_url, as: :node do |form| %>
  <%= render "form", f: form %>
  <p><%= form.submit %> or <%= link_to "Cancel", admin_book_nodes_path %></p>
<% end %>

Log:

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)

It works fine if I disable per form CSRF tokens in the controller (self.per_form_csrf_tokens = false) so my issue is really at that level.

The session does not seem to be reset at any point.

Interestingly, when the form is first loaded, the authenticity token in the header's menage tag is different from the token in the form. The meta tag is also at the bottom of the header's tags. When I then reload the tokens are the same in both the meta tag and the form, and the meta tag is at the top of the header's tags.

Update:

I think that the issue is down to Turbolinks.

When the form page is accessed from another page in the app, an XHR request is fired by Turbolinks, and I encounter the issue.

However, when I reload the page the browser reloads it and I don't see the issue.


Solution

  • I have raised an issue on Rails.

    After further investigation it seems that the issue is due to option :url in form_for.

    See: Issue #24257 (not resolved yet)