For some reason, this did not work (rails 3.2.11) for any session data that was installed on the subdomain. The fix required a piece of custom middleware. The following is a brief description of this solution.
tl; dr: You need to write your own Rack middleware. You need to add it to your conifg/environments/[production|development].rb . This is on Rails 3.2.11
Cookie sessions are usually only stored for the top-level domain.
If you look in Chrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com} , you will see that there will be separate entries for sub1.yourdomain.com and othersub.yourdomain.com and othersub.yourdomain.com
The challenge is to use the same session storage file in all subdomains.
Step 1: add a custom middleware class
Here is the Rack Middleware . Some relevant rack and rail resources:
Here is a custom class that you should add to lib It was written by @Nader , and you should all thank him.
# Custom Domain Cookie # # Set the cookie domain to the custom domain if it present class CustomDomainCookie def initialize(app, default_domain) @app = app @default_domain = default_domain end def call(env) host = env["HTTP_HOST"].split(':').first env["rack.session.options"][:domain] = custom_domain?(host) ? ".#{host}" : "#{@default_domain}" @app.call(env) end def custom_domain?(host) host !~ /#{@default_domain.sub(/^\./, '')}/i end end
Basically, this means that it will display all your cookie session data back into the same cookie, which is equal to your root domain.
Step 2: Add to Rails Config
Now that you have a custom class in lib, make sure it automatically loads it. If that doesn't mean anything to you, check here: Rails 3 Startup
First of all, make sure that you are system-wide using the cookie store. In config/application.rb we tell Rails to use cookie storage.
# We use a cookie_store for session data config.session_store :cookie_store, :key => '_yourappsession', :domain => :all
The reason mentioned here is related to the line :domain => :all . There are other people who suggested specifying :domain => ".yourdomain.com" instead of :domain => :all . For some reason, this did not work for me, and I need a custom middleware class, as described above.
Then in config/environments/production.rb add:
config.middleware.use "CustomDomainCookie", ".yourdomain.com"
Please note that the previous point is necessary. See “ Subdomain cookies sent to a parent domain request? ” For what.
Then in config/environments/development.rb add:
config.middleware.use "CustomDomainCookie", ".lvh.me"
The lvh.me trick maps to the local host. This is amazing. See this Railscast for subdomains and this note for more information. Information.
Hope this should do it. I'm honestly not quite sure why this process is confusing, because I feel that cross subdomains are common. If anyone has any further information on the reasons underlying each of these steps, please inform us in the comments.