Open venkat071982 opened 8 months ago
I'm stuck on this too, but only in production
Encoutering the exact same on my local server, with ActiveAdmin.
I am using redis store in rails7 syntax changed so that its not working I did like following in session_store.rb its working fine config.session_store :redis_store, servers: "redis://localhost:6379/0/session", key: '_your_app_session_key', expires_in: 1.day, prefix: 'myapp:sessions:'
We fixed it on our end by removing the following from config/application.rb
:
config.action_dispatch.cookies_same_site_protection = :none
config.action_controller.default_protect_from_forgery = false if ENV['RAILS_ENV'] == 'development'
I had the same problem when upgrading from rails 7.0 to 7.1
Same issue after upgrading to Rails 7.1.2
It works on development, but not on staging/production
FORM (SIGN UP) Head
Form
<form data-turbo="false" class="space-y-4" id="new_user" action="/en/users" accept-charset="UTF-8" method="post">
Registration controller
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:email, :password, :password_confirmation, :terms_of_service, :coupon_code, :currency_code, :referral, :locale, :referrer, :via, utm: [:source, :campaign, :medium, :content, :term] ])
end
config/enviroment/staging.rb
config.cache_store = :redis_cache_store, { url: ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" }}
config.session_store :cookie_store, key: "_session", expire_after: 1.year
Gemfile.lock devise (4.9.3) rails (7.1.2)
I noticed in dev console that the session_id is named ["session_id
I had the same problem when upgrading from rails 7.0 to 7.1
Same for me, can I ask you how did you fix?
I had the same problem when upgrading from rails 7.0 to 7.1
Same for me, can I ask you how did you fix?
Upgrade to ruby 3.2, then be sure to have
config/enviroment/production.rb
config.session_store :cookie_store, key: "_example_session", expire_after: 1.year, domain: ".example.com"
app/controller/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
If you use Passenger, then add this to Gemfile. I was inspecting the Chrome Dev console and the cookie name cointaned a unrecognized character like ["session_id instead of session_id.
gem 'rack', '~> 2.2'
I had the same problem when upgrading from rails 7.0 to 7.1
Same for me, can I ask you how did you fix?
I found that changing the session and so on didn't work, and then upgrading to rails 7.1.2 solved it
I was running into the same issue with Rails 7.1.2 and Devise 4.9.3, what fixed it in my case (based on this comment: https://github.com/heartcombo/devise/issues/5298#issuecomment-1775911730) was the puma upgrade to 6.4.2 from 5.6.4.
Same problem with rails 6.1
In my case I fixed it in config/initializers/session_store.rb
:
by adding domain: :all
and changing cookie_store key
to handle various environments like _#{Rails.env}
.
Something like that:
Rails.application.config.session_store :cookie_store, key: "_my_name_#{Rails.env}", expire_after: 1.year, domain: :all
Also I'm using nginx in development, so, for my proxy I've ensured that the host header is correct to handle same origin verification problem (if you have a frontend on a separate localhost:port) and combining them together on the same host by using nginx:
location / {
proxy_set_header HOST $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_request_headers on;
proxy_pass http://rails_backend;
proxy_buffers 8 1024k;
proxy_buffer_size 1024k;
}
Note: rails_backend
is the upstream. I had issues when I used $host
, but not $http_host
Might be useful for someone like myself who struggled with the issue for a few hours
Faced similar issue, here is the story. Maybe it could help someone.
When removing domain: :all, tld_length: 2
from the session_store
configuration.
Going from:
# kept only meaningful elements of the configuration
Rails.application.config.session_store :redis_store,
key: "_session_identifier", expire_after: 14.days, domain: :all, tld_length: 2, secure: true
To
Rails.application.config.session_store :redis_store,
key: "_session_identifier", expire_after: 14.days, secure: true
The issue was visible immediately after deployment, no need to way for stale cookies...
Context
Devise is configured to use the :rememberable
feature (remember_user_token
cookie)
We moved an application from the domain (example.com) to multiple subdomains (eu.example.com and now us.example.com) with different application servers. During the migration we wanted users to stay logged in, that's why domain: :all, tld_length: 2
to the session_store
configuration, so that cookies on example.com
could be reused on eu.example.com
domain.
Before the change the server would set a _session_identifier
cookie on the .example.com
domain.
After removing domain: :all, tld_length: 2
. This resulted in the server generating a new _session_identifier
cookie with the same name as the previous one but set on eu.example.com
.
As the user was identified by the remember_user_token
, users would still be logged in. But when submitting a form they would face the ActionController::InvalidAuthenticityToken
.
Why ?
After deployment. When getting a page the server generates a csrf_token
which is stored in the session and inserted in the html page (meta tag and hidden form field). the session uses the new configuration no domain: :all, tld_length: 2
. which results in a new _session_identifier
cookie sent to the browser.
When submitting the form the browser would send the two _session_identifier
cookies, one generated when the configuration was domain: :all, tld_length: 2
and one new generated with domain: :all, tld_length: 2
.
According to the HTTP RFC:
- Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times. This results in the browser sending the oldest
_session_identifier
cookie first (the one created withdomain: :all, tld_length: 2
) and the latest_session_identifier
cookie last. cookies have different values (session identifier).
The server will use the oldest _session_identifier
cookie to retreive a session from the session store. The old session would not contain the same csrf_token
as the one submitted by the browser.
How did I fix it ?
1) Changed the session cookie name
# Users would still be logged in thanks to the `remember_user_token`
Rails.application.config.session_store :redis_store,
key: "_new_session_identifier", expire_after: 14.days, secure: true
2) Cleanup previous cookies
class ApplicationController < ActionController::Base
before_action do
if request_format == :html
cookies.delete(: _session_identifier, domain: :all)
cookies.delete(:remember_user_token, domain: :all)
current_user.remember_me! if current_user
end
end
end
We fixed it on our end by removing the following from
config/application.rb
:config.action_dispatch.cookies_same_site_protection = :none config.action_controller.default_protect_from_forgery = false if ENV['RAILS_ENV'] == 'development'
is this safe?
Ruby 3.2.2 Rails 7.0.8 Devise 4.9.2
Current behavior
Extremely frustrating. All of a sudden I try to login/register I get Can't verify CSRF token authenticity..
I didn't do any changes and it was all working fine 1h ago.
Stack trace:
.... def handle_unverified_request raise ActionController::InvalidAuthenticityToken, warning_message end end end ... PS: Yes I have the CSRF and CSP tags:
<%= csrf_meta_tags %> <%= csp_meta_tag %>