Reviving this old thread with a I am developing a site that needs to be
accessible to mobile phones, and I am having issues with session
tracking.
While the default "cookie_only" session tracking makes a lot of sense
(it prevents session fixation attacks), there are these cases when your
clients do not support cookies (say, many mobile phones, for example)
and you just need to do request-parameter-based session tracking.
One should be able to use the "cookie_only" session option and set it to
"false" where appropriate, but this is seriously broken in Rails 2.3.
From my tests so far:
1) Setting a default by adding "config.action_controller.session =
{:cookie_only => false}" in environment.rb DOES work.
2) Inside your controller (say, a before_filter method),
"request.session_options[:cookie_only] = false" to false will NOT work.
Unfortunately, 1) is not an acceptable solution, as it opens the whole
site to session fixation attacks.
FWIW, I think I have traced down the culprit to the load_session method
in active_store.rb around line 165:
sid = request.cookies[@key]
unless @cookie_only
sid ||= request.params[@key]
end
This code becomes a problem in 2.3, because the session has been pushed
down to the Rack middleware layer, where your abstract_store gets
initialized once and for all, way before any of your controller code
gets executed. As a result, your abstract_store's @cookie_only and @key
are set once and for all, according to the default session options. Any
further changes to the session_options[:cookie_only] or
session_options[:key] will simply be ignored.
Here is a tentative monkey patch that restores the proper functionality
of session_options[:cookie_only] and session_options[:key].
HTH.
#######################################################################
# Monkey patch to allow per-controller/action setting of :cookie_only
# and :key session options
#######################################################################
module ActionController
module Session
class AbstractStore
private
def load_session(env)
request = Rack::Request.new(env)
key = request.session_options[:key]
cookie_only = request.session_options[:cookie_only]
sid = request.cookies[key]
unless cookie_only
sid ||= request.params[key]
end
sid, session = get_session(env, sid)
[sid, session]
end
end
end
end
--
Posted via http://www.ruby-forum.com/.
Yes, I just found out myself the patch is only a partial solution: it
worked on my simple prototype, but once integrated into my production
system, it stopped working. Like you, I found that "load session" was
happening before "set option".
The problem is that the session is automatically loaded as soon as
something tries to use it. So if some plugin uses the session before
your controller gets control, then the session will be loaded before
your before_filter can set the options correctly.
What you can do to find the culprit: use the ruby debugger and add a
"debugger" statement inside the load_session monkey patch function, then
run your server with "script/server --debugger". When you try to access
you site, your console will drop into the debugger, and you can issue a
"where" command, that will give you a stack trace, so you can find out
what triggered the call to load_session.
In my case, it was the render_component plugin.
Unfortunately, I do need the render_component plugin (for my admin pages
that use ActiveScaffold)...
So, the problem is still open... Can anyone help? Should I fill a bug
report?
--
Yves-Eric Martin