Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Rails 6.1, trouble with session management, sessions behave weirdly

Post

Rails 6.1, trouble with session management, sessions behave weirdly

+6
−0

I am at a complete dead end with Rails sessions.

I have an old Rails project. It started with Rails 3 or 4, and it is now running on Rails 6.1.7.10, the code has been updated carefully. I use sessions to keep track of logged-in users (just the user ID and the expiry). The sessions have always been used without much config. My total amount of config is now (in config/initializer/session.rb):

Rails.application.config.session_store :cookie_store, key: '_qc24_session', domain: :all

and, since I use Devise (v 4.9.4, in vendor/mymodules/config/initializer/devise.rb):

config.skip_session_storage = [:http_auth]

I am running into several problems.

  1. Increasingly, people need to sign in twice.

    The first time somehow the session will not get written, although if I read from the session directly after writing into it, the value is written. What happens is:

    • The user logs in, the session gets written according to the logs, the controller redirects to the user's start page.
    • The controller method there tries to retrieve the session data, notices the session is empty and redirects the user to the login page.
    • The user inputs their login data a second time, presses the login button again, and then the login succeeds.
  2. All guides state that you read and write from/to sessions using symbolic keys, but I need to use string keys.

    If I try using symbolic keys, the sessions will not work at all. I've posted on StackOverflow about that. I need to use string keys.

  3. session_store :cache_store shows the same behaviour.

    The bit mentioned in point 1 pointed to some kind of async problem, so I activated caching in dev.mode and changed the session store type to

    Rails.application.config.session_store :cache_store, key: '_qc24_session', domain: :all
    

    Then I get the same behaviour: The user needs to log in twice.

I read and write from/to sessions simply by using session['user_id'].

I can not find any sort of comprehensive information that allows me to begin debugging this situation. It always seems that all you do is state which kind of session_store you want, Rails does the rest. Obviously this is not true.

It is perfectly possible that owing to past migrations of Rails versions the project is not configured correctly, but how can I figure out what is wrong?

History

1 comment thread

Some feedback and details (6 comments)
Some feedback and details
plain_toast‭ wrote 7 months ago · edited 7 months ago

I have a response to my question about string keys. Since I use the default session store (cookie_store), my session gets serialized as JSON. It seems it does not get restored to the original form when the call returns from the frontend. So that's all right. I've got some other feedback saying that calling reset_session before login might cause the CSRF token to be deleted too and cause the effect I see. However, I don't use reset_session before login (owing to specific reasons). I just delete the relevant info from the session via session.delete('user_id') or similar.

plain_toast‭ wrote 7 months ago

One more bit of information. I don't use Devise. It was there in my project all the time but I never used it. I've since uninstalled it. The error persists. Sigh.

Oleg Valter‭ wrote 6 months ago

Can you track down logs for the affected requests? There can be something along the lines of "Filter chain halted as ... rendered or redirected" that can serve as a starting point for further investigation.

plain_toast‭ wrote 6 months ago · edited 6 months ago

Yes, there is. That filter chain statement says "redirected to login screen". The redirect happens because the session ist empty in spite of its having been written to before. And I have been logging the session too. It's written to correctly; the puts statement outputs the session in exactly the state I would expect it to be: After authenticating the user the user id is written to the session. The log statement is *** session currently is: {user_id: <value>}***. Then I redirect the user to the start page of the user screen, which redirects because the session suddenly is empty again, the log statement is *** session currently is: {}***. That's all there is; the session is lost. And it happens time and again, occasionally, and in no case it's reproducible. It must be some kind of async problem. Personally, I kind of feel the fact that the "session is written lazily" (as per documentation) is the problem.

Oleg Valter‭ wrote 6 months ago

Thanks! Yeah, that's weird... Do you call protect_from_forgery on your application controller (just to rule it out, you can set skip_before_action :verify_authenticity_token that should suppress protection)? It's supposed to skip GET & HEAD requests, but it's possibly related given that the default action is to substitute the session with an empty one without failing the request.

plain_toast‭ wrote 4 months ago

Sorry, haven't been around for a while. I meanwhile implemented a parallel session management using the database, that's how frustrated I was. No, I don't call protect_from_forgery on the application controller. I removed that line as I understood it's now included by default in ActionController::Base.