Track Session Id Change on Devise

Devise change session id? The same question poped up when earlier on our project we need to keep track of what session id being used.

Yes, Devise change session id, sometimes. It happen after authenticate user and after logging out user. On after authenticate user, only session id that being changed, session content is remain the same. But after log out, session is cleared out, means its content is gone. The purpose of this behavior is to prevent Session Fixation attack, when somebody is using your session to access a website that you logged in into. This is maybe one of the reasons you should start using Devise.

But, under the hood, it's Warden (a gem that Devise depends on) that responsible for session ID being change after certain action. When setting a user, like after authentication, Warden set :renew options to true to issue Rack to renew session id on the next request. And reset session after log out.

To track session id we need to use Warden callbacks to check if session id is changed. For example, we can create singleton class to store current session id, let's call it SessionTracker:

class SessionTracker  
  attr_accessor :session_id

  def self.get_instance
    @session_tracker ||= SessionTracker.new
  end

  def self.update_session_id_if_new(session_id)
    tracker = get_instance
    return unless tracker.session_id != session_id
    tracker.session_id = session_id
  end
end  

Then on on_request callback, we check stored session id with session id from Rack, if its different store it to SessionTracker, like so:

Warden::Manager.on_request do |proxy|  
  session_id = proxy.env['rack.session'].id
  SessionTracker.update_session_id_if_new(session_id)
end  

All code above should be put under config/initializers folder.