Devise: Devise rails session ID and first redirection

Created on 13 Aug 2015  ·  2Comments  ·  Source: heartcombo/devise

It turns out that getting the session ID (with session[:session_id]) after login with Devise (authentication gem) (either in session_controller or in after_sign_in_path_for) does not return the same thing before and after redirecting for the first time, after logging-in.

Is anyone able to explain me why ? Is there any way to get the final session ID before redirecting ?

Most helpful comment

Is anyone can explain me why ?

I'll try. In short:

  • Devise has nothing to do with it
  • Warden has something to do with it - it's setting :renew option on session, after setting user (proxy, spec)
  • Actual action takes place in in Rake::Session::Abstract#commit_session which updates session_id (by calling destroy_session and set_session implementented in ActionDispatch::Session::CookieStore)

Is there any way to get the final session ID before redirecting ?

Sure it is. Bear in mind that Warden is changing session_id after authentication to prevent session fixation attacks, so in overriden devise controller you should manually change session_id in addition to disabling :renew session option. This will do:

session.options[:id] = session.instance_variable_get(:@by).generate_sid
session.options[:renew] = false

All 2 comments

Is anyone can explain me why ?

I'll try. In short:

  • Devise has nothing to do with it
  • Warden has something to do with it - it's setting :renew option on session, after setting user (proxy, spec)
  • Actual action takes place in in Rake::Session::Abstract#commit_session which updates session_id (by calling destroy_session and set_session implementented in ActionDispatch::Session::CookieStore)

Is there any way to get the final session ID before redirecting ?

Sure it is. Bear in mind that Warden is changing session_id after authentication to prevent session fixation attacks, so in overriden devise controller you should manually change session_id in addition to disabling :renew session option. This will do:

session.options[:id] = session.instance_variable_get(:@by).generate_sid
session.options[:renew] = false

How can we get the new session id after authentication? session.options[:id] shows the old value

Was this page helpful?
0 / 5 - 0 ratings