Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Users take sessions of other users when sessions are stored in memcached (Rails)

I have a very weird problem, when storing my session in Memcached. From time to time some users takes the session of others. E.g. John, becomes logged in as Maria, Maria as Chris and so on.

I use Rails 2.3.4, but the same problem has been happening with earlier versions of Rails. I use only one Memcache server and it's running on the same machine. The problem with debugging this is that I can not reproduce it.

I'll be very glad if anybody can guide me how to solve this problem or debug it. I'll be also happy if you are using Memcached for sessions and you share your example confgs.

These are my configurations:

# memcache options
memcache_options = {
  :c_threshold => 10_000,
  :compression => false,
  :debug => false,
  :namespace => 'app_prod',
  :readonly => false,
  :urlencode => false,
}
memcache_servers = ['localhost:11211']

CACHE = MemCache.new(memcache_options)
CACHE.servers = memcache_servers

config.cache_store = :mem_cache_store, memcache_servers, memcache_options
config.action_controller.session_store = :mem_cache_store
config.action_controller.session = {
  :session_key => '_appname',
  :cache => CACHE,
#    :expires => 10,
#    :session_expires => 10,
  :secret      => '5391aaaaaaaaaa56f8e8234beb638b97b32bbbbbbbbbbcc9dcae2beccccccccc89e8b508328def001a368da0678b061eb0e9d5a82a5ac94c8d35bd31a9a49e1'
}

Thank you in advance, Stan

like image 302
Stan Bright Avatar asked Oct 06 '09 08:10

Stan Bright


People also ask

How are sessions stored in Rails?

Rails uses ActionDispatch::Session::CookieStore as the default session storage. Learn more about other session storages in Action Controller Overview Guide. Rails CookieStore saves the session hash in a cookie on the client-side.

Where does Rails store session data?

In Rails, session object is sent back and forth inside cookies. When you set session[:user_id] = 3 inside of your controller action, the response sent from that action will have a header Set-Cookie: my-session-cookie .

How does devise session work?

Devise uses the session storage that Rails is configured to. So it depends on which session storage you will use in your app, not on Devise. If you want to store the session data in the database, then yes, you need to tell Rails about that and run the Rails generator that creates the database table for you.

What is session in Ruby on Rails?

Rails session is only available in controller or view and can use different storage mechanisms. It is a place to store data from first request that can be read from later requests. Following are some storage mechanism for sessions in Rails: ActionDispatch::Session::CookieStore - Stores everything on the client.


2 Answers

I've seen this and found it very difficult to debug.

If you're using passenger, you may want to look at using the conservative method for spawning new servers.

The default method has servers sharing a single socket to memcache.

The docs discuss it in more detail. http://www.modrails.com/documentation/Users%20guide%20Apache.html#_example_1_memcached_connection_sharing_harmful

like image 181
AndyWatts Avatar answered Oct 13 '22 15:10

AndyWatts


This could be a problem with the session cookie flipping between two values. For example, you might have one assigned to example.com and another to www.example.com, a common situation with some sites that respond to both without redirecting to make one canonical.

The behavior of some browsers is to send the cookie matching the longest subdomain, whereas others actually send through both values, and they may differ. This could lead to a session toggling between two different values at unpredictable times.

One way to fix this is to lock your cookies to .domain.com instead of letting it assume the www or www-less version, if this is the case, or redirecting to force the use of one only.

Another way to diagnose the nature of the session situation is to have a debugging page that displays the session ID, or embed it in the page output somehow so someone who encounters the problem can help in diagnosing it. Something like /session_info is easy to create.

like image 3
tadman Avatar answered Oct 13 '22 17:10

tadman