I am new to Rails and am experiencing a strange problem that I do not understand. I use ActiveRecord as a session repository and must add a session identifier as a JSON response property for all requests. I also use Devise if this affects the situation. The problem is that if the request is executed by the user without cookies (or, at least, without the session identifier in the cookie), session.id is empty or - attention - please, not the same value that is set in the response cookie.
For debugging, I add this code as after_filter in the ApplicationController:
puts session.id puts request.session_options[:id]
Both values ββare the same. They correspond to the value in the cookie, if present. Otherwise, if the session identifier is not in the cookie, the cookie set after this request has a different meaning.
My opinion is that session_id gets a new value after it is actually stored in the database, where it should be unique. Database Transfer:
def change create_table :sessions do |t| t.string :session_id, :null => false t.text :data t.timestamps end add_index :sessions, :session_id, :unique => true add_index :sessions, :updated_at end
My question is: how can I get the actual session.id value of a new session before the first response is displayed?
UPD:
I just created a new Rails application that uses ActiveRecord session storage without Devise, and I can get session.id that will be set in the cookie just before the response using this application code controller:
class ApplicationController < ActionController::Base after_filter :show_session def show_session puts session.id end end
But in my existing application with Devise, I get a value that really looks like a session identifier, but this does not match the value set in the cookie using the Set-Cookie response header, and the value actually stored in the session table in the database, It looks like Devise has a conflict with ActiveRecord session storage. One needs to go deeper to understand this.
UPD 2
Looks like I found the root of the problem. As I said, I use Devise to log in with Omniauth. According to the documentation, the sign_in method resets the session identifier for security reasons. But after that, reset session.id returns the old value that was automatically set. I use this code as an Omniauth callback:
def facebook_access_token sign_in @user puts session.id end
And in the console, I get a session ID different from the one set in the Set-Cookie response header. If I comment out the line "sign_in", these values ββmatch. New question: how can I get a new session id value after reset inside the sign_in method? Is this an internal implementation of Warden / Devise or something else?