Rails ActiveRecord store and new session -
i new rails , experience strange issue don't understand. use activerecord session store , need add session id property of json responses requests. use devise if have impact on situation. problem if request made user without cookies (or @ least without session id in cookie) session.id empty or - attention, please - not same value set in response cookie.
for debugging, add code after_filter applicationcontroller:
puts session.id puts request.session_options[:id]
both values same. match value in cookie if present. otherwise, if session id not present in cookie, cookie set after request has different value.
my opinion session_id gets new value after saved database, have unique. db migration:
def change create_table :sessions |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: how can actual session.id value of new session before first response rendered?
upd:
i created new rails app uses activerecord session store without devise, , can session.id going set in cookie before response code id application controller:
class applicationcontroller < actioncontroller::base after_filter :show_session def show_session puts session.id end end
but in existing app devise value looks session id, doesn't match value set in cookie via set-cookie response header , value saved sessions table in database. looks devise have conflict activerecord session store in way. need go deeper figure out.
upd 2
looks found problem roots. said, use devise authorization omniauth. according documentation, sign_in method resets session id security reasons. after reset session.id returns old value, had been automatically set. use code omniauth callback:
def facebook_access_token sign_in @user puts session.id end
and in console session id different 1 set in set-cookie response header. if comment "sign_in" line, these values match. new question: how can new session id value after been reset inside of sign_in method? internal warden/devise implementation or something?
renewing still important , should not disable it
also new session id generated after execution of controller, therefore after have chance set response sent client.
the solution manually trigger renewing of session id
in applicationcontroller
add method:
protected def commit_session_now! return unless session.options[:renew] object = session.options.instance_variable_get('@by') env = session.options.instance_variable_get('@env') session_id = object.send(:destroy_session, env, session.id || object.generate_sid, session.options) session_data = session.to_hash.delete_if { |k,v| v.nil? } object.send(:set_session, env, session_id, session_data, session.options) session.options[:renew] = false session.options[:id] = session_id end
then in controller call method before getting session id response
def my_action ... commit_session_now! render json: {session_id: session.id}, status: :ok end
the code in commit_session_now!
comes rack::session::abstract::id#commit_session
https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb#l327
Comments
Post a Comment