Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Rails 3 session_store domain :all really do?

Updated question to make it more clear

I understand that you can set the domain of your session_store to share sessions between subdomains like this: Rails.application.config.session_store :cookie_store, :key => '_my_key', :domain => "mydomain.com"

in Rails 3, what does the setting :domain => :all do? It can't let you share sessions across top-level domains, cookies can't do that. The documentation says it assumes one top level domain. So what happens if multiple domains access your app?

In my app, my users can create personal subdomains of one main domain, but then can also access that subdomain via their own custom domain.

What is the correct session_store domain setting so that I can: a) share sessions across all domains of my primary domain, eg "mydomain.com" b) users who access their personal subdomain eg "user1.mydomain.com" via a CNAME custom url like "some.otherdomain.com" can still create separate sessions.

Thanks

like image 845
Nader Avatar asked Oct 30 '10 19:10

Nader


2 Answers

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 
like image 104
Nader Avatar answered Oct 11 '22 18:10

Nader


I didn't think any of the existing answers directly answered the question in the title so I wanted to chip in.

When the client (browser) goes to a website, the website tells the client to set a cookie. When it does so, it specifies the cookie name, value, domain, and path.

:domain => :all tells Rails to put a dot in front of the cookie domain (which is whatever host your browser has browsed to), such that the cookie applies to all subdomains.

Here is the relevant code from Rails 4.1 (actionpack/lib/action_dispatch/middleware/cookies.rb):

  def handle_options(options) #:nodoc:     options[:path] ||= "/"      if options[:domain] == :all       # if there is a provided tld length then we use it otherwise default domain regexp       domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP        # if host is not ip and matches domain regexp       # (ip confirms to domain regexp so we explicitly check for ip)       options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ domain_regexp)         ".#{$&}"       end     elsif options[:domain].is_a? Array       # if host matches one of the supplied domains without a dot in front of it       options[:domain] = options[:domain].find {|domain| @host.include? domain.sub(/^\./, '') }     end   end 

I see you've already answered the second part of your question about allowing subdomains to have separate sessions.

like image 38
Tyler Collier Avatar answered Oct 11 '22 19:10

Tyler Collier