12

Background Details

I am using Devise for authentication to login to a Rails 5 application.

Whenever I bundle either the Audited or Paper Trail gem, when I attempt to #create a new session (via the sign in form - /users/sign_in), I receive the following error:

ActionController::InvalidAuthenticityToken

Environment Details

Ruby 2.3.1

Gems:

  • rails 5.0.2
  • devise => 4.2.1
  • paper_trail => 7.0.1

Steps to Reproduce:

  1. Create Rails 5 application
  2. Add Devise gem
  3. Add Audited or Paper Trail gem
  4. Attempt to login
aldefouw
  • 533
  • 1
  • 4
  • 12
  • 1
    Do you have `protect_from_forgery with: :exception` in application_controller? – whodini9 Apr 11 '17 at 21:02
  • 2
    @whodini9 - Bingo. That was the cause of the error. I changed it to this: `protect_from_forgery prepend: true` And then things were happy. Thanks for the help. – aldefouw Apr 11 '17 at 21:06

6 Answers6

33

As it turns out, Devise documentation is quite revealing with regard to this error:

For Rails 5, note that protect_from_forgery is no longer prepended to the before_action chain, so if you have set authenticate_user before protect_from_forgery, your request will result in "Can't verify CSRF token authenticity." To resolve this, either change the order in which you call them, or use protect_from_forgery prepend: true.

The fix was to change code in my application controller from this:

 protect_from_forgery with: :exception

To this:

 protect_from_forgery prepend: true

This issue did not manifest itself until I attempted adding Audited or Paper Trail gems.

Mauro
  • 1,241
  • 22
  • 26
aldefouw
  • 533
  • 1
  • 4
  • 12
  • Worked for me, strangely enough, if you were still logged in, the problem doesn't appear, so it seemed intermittent. – Steve May 05 '17 at 14:41
  • 1
    @JohnLinux - I experienced the same thing. I don't think it is intermittent though. I think that Devise is sending you through a different call stack when you are logged in. – aldefouw May 30 '17 at 16:48
  • 2
    This was causing me a lot of confusion and frustration. Multiple other posts mention 'moving' it, but non specific the prepend. Thanks. – DNorthrup Jul 18 '17 at 02:52
  • The proposed change is actually changing more. You probably want `protect_from_forgery with: :exception, prepend: true`, but you end up with `protect_from_forgery with: :null_session, prepend: true` as :null_session is the default value of `with:` – jewilmeer Sep 21 '18 at 14:56
1

This happened to me on my development machine. Turns out I was setting

Rails.application.config.session_store

for security purpose in production. And somehow in this code gets run on development mode. And I have to comment out this line and it works fine now.

Rails.application.config.session_store :cookie_store, key: '_my_session', secure: true, same_site: :strict
1

Another thing to try for anyone running into this is to add the following to your environment configuration file:

config.action_controller.forgery_protection_origin_check = false

For me, production was working correctly but staging and development were not and this fixed it for me.

0

In my project we have that problem and we can't to override protect_from_forgery. The solution founded is indicate the github of audited and worked for me.

Put this in gemfile:

gem "audited", github: "collectiveidea/audited"
msfreire
  • 494
  • 6
  • 10
  • 1
    This doesn't seems to be an answer to the OP question? – danglingpointer May 29 '17 at 19:34
  • 1
    @LethalProgrammer, sorry I don't understand the OP question. My answer is to work without edit _protect_from_forgery_, because my project using a before_action callback to validate something before session create in devise. Sorry if is not clear in my answer. – msfreire May 29 '17 at 19:47
  • @msfreire - are you suggesting that you can use `protect_from_forgery with: :exception` in your application controller if you use the github branch that you posted? – aldefouw May 30 '17 at 16:46
  • 1
    @aldefouw Yes. I dont need to change to `protect_from_forgery prepend: true` if you put the branch in gem file. I`m using rails 5.0.1, try that if you using rails 5+ – msfreire May 31 '17 at 01:15
0

As mentioned in the documentation.

For Rails 5, note that protect_from_forgery is no longer prepended to the before_action chain, so if you have set authenticate_user before protect_from_forgery, your request will result in "Can't verify CSRF token authenticity." To resolve this, either change the order in which you call them, or use protect_from_forgery prepend: true.

I have used something like this and it works for me.

class WelcomeController < ::Base
    protect_from_forgery with: :exception
    before_action :authenticate_model!
end
Francisco Quintero
  • 730
  • 1
  • 13
  • 20
Yashu Mittal
  • 1,478
  • 3
  • 14
  • 32
0

The solution for me was to manually go to my browser's settings and delete the cache.

jethro
  • 168
  • 3
  • 13