I bumped my application to Rails 7.1, and on my development server, signing in using my Devise setup works fine. However, on my staging server (RHEL7 using nginx), authentication no longer works.
At first, it claims that it cannot verify the authenticity_token. The token is being provided in the <head>
as well as a hidden field in the sign-in form. Just to try to get it working, I tried to skip_forgery_protection in my locally-provided Devise::SessionsController (with no other modifications from the file generated by the gem) and oddly that didn’t work, the only way I got around the protect_from_forgery was to copy the DeviseController inherited by the generated controllers from the devise repo and put skip_forgery_protection in that (Even removing protect_from_forgery from my ApplicationController entirely, as well as removing both authenticity_token tags, did not stop the CSRF error during sign-in).
Once I stopped seeing the CSRF error in the logs, I had a different problem. I authenticated, which would redirect me to a page that requires authentication, then that page would redirect me back to sign-in. In the logs, I see Devise increment my user record’s log_in_count, so it seems like the authentication was accepted. But then it would act like I’m not logged in. So my hunch became that the current_user value was not being properly set in the session cookie, so I started messing with that. I was able to recreate this symptom on my development server if I set my cookie_store config to use secure: true on development (previously it was only set to be secure on non-dev envs). However, switching secure: false didn’t help staging at all.
So I have a lead, but I have hit a wall. It seems like devise is silently failing at this point, failing to store the authenticated user. But it seems like if this was an issue someone would’ve caught it by now, so I still think it is some configuration in my app. Any ideas of where to look that might cause something like this?
Ruby 3.1.4
Rails 7.1.1
Devise 4.9.3
Tested on Chrome/Brave/Safari, no difference.
2
Answers
We are having the same issue in a similar setup.
Sign in doesn’t work, but users can still enter through recovering from forget password link, then the session works fine.
Our app haven’t migrated from turbolinks to turbo.
It might be related to:
https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-%5BHotwire-Turbo-integration%5D
I have a very similar sounding problem though I am not using Devise.
Everything was working with rails 7.0.8 but when I upgraded to 7.1.1, though my tests still worked and the development app seemed fine, in production there were exceptions ("Can’t verify CSRF token") when POST-ing login credentials.
Some logging related to code in ActionController::RequestForgeryProtection put into a prepend_before_action in my session controller revealed a significant difference between production and development. Both appeared to correctly receive the token from the form (in request_authenticity_tokens) but in production compare_with_global_token returns false (eventually causing an exception) while in development the same method returns true (avoiding any error and eventually leading to a successful login).