Rails - Multiple Top Level Domains and a Single Session/Cookie

Rails session_store multiple domains

See: What does Rails 3 session_store domain :all really do?
The selected answer can probably help you to allow common sessions between subdomains and separate sessions between top level domains. To make the same session be valid in different top level domains, is much trickier, but perhaps this question could help you forward: Rails - Multiple top level domains and a single session/cookie

Share session (cookies) between subdomains in Rails?

As it turns outs 'domain: all' creates a cookie for all the different subdomains that are visited during that session (and it ensures that they are passed around between request). If no domain argument is passed, it means that a new cookie is created for every different domain that is visited in the same session and the old one gets discarded. What I needed was a single cookie that is persistent throughout the session, even when the domain changes. Hence, passing domain: "lvh.me" solved the problem in development. This creates a single cookie that stays there between different subdomains.

For anyone needing further explanation, this is a great link:
http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/

Delete Session Cookies Across Multiple Subdomains in Rails 3

The key is really how you set your session cookies, because you can't delete a subdomain cookie (username.myapp.com) from a top-level domain (myapp.com). To solve this you'll want all your shared session cookies to be set under the myapp.com domain. To do this, setup your sessions in the following way:

Rails.application.config.session_store :cookie_store, :domain => 'myapp.com'

That way, when you destroy your session (session[:id] = nil) you'll be removing the shared cookie. I believe you will also have to delete the session using session[:id] instead of session[:user_id].

What does Rails 3 session_store domain :all really do?

OK, the way to accomplish this is to set the domain on the session cookie dynamically. To do this early enough it should be done as rack middleware:

# Custom Domain Cookie
#
# Set the cookie domain to the custom domain if it's 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


Related Topics



Leave a reply



Submit