Rails 4 Authenticity Token
Solution 1:
I think I just figured it out. I changed the (new) default
protect_from_forgery with: :exception
to
protect_from_forgery with: :null_session
as per the comment in ApplicationController
.
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
You can see the difference by looking at the source for request_forgery_protecton.rb
, or, more specifically, the following lines:
In Rails 3.2:
# This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
reset_session
end
In Rails 4:
def handle_unverified_request
forgery_protection_strategy.new(self).handle_unverified_request
end
Which will call the following:
def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end
Solution 2:
Instead of turn off the csrf protection, it's better to add the following line of code into the form
<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>
and if you're using form_for or form_tag to generate the form, then it will automatically add the above line of code in the form
Solution 3:
Adding the following line into the form worked for me:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
Solution 4:
I don't think it's good to generally turn off CSRF protection as long as you don't exclusively implement an API.
When looking at the Rails 4 API documentation for ActionController I found that you can turn off forgery protection on a per controller or per method base.
For example to turn off CSRF protection for methods you can use
class FooController < ApplicationController
protect_from_forgery except: :index