The right way to share subdomain login sessions in Rails 3?

All the information I found on the Internet about this says to use something like

  Login :: Application.config.session_store: cookie_store,: key => '_login_session',: domain => '.domain.com'

And use the same key for all subdomains that I want to share with this session. When I do this, authentication does not pass between subdomains. In fact, when I attend any of the supposedly shared sessions, the initial session is overwritten

i.e. on login.domain.com, I run authentication, which returns the username and user_id session. Then I go to sub.domain.com, which should return the same information as login.domain.com, but it is not. After that, I return to login.domain.com and I am no longer authenticated there.

In the sub.domain.com file, the session_store.rb file looks like this:

  Something :: Application.config.session_store: cookie_store,: key => '_login_session',: domain => '.domain.com' 

I used: everything for the domain value: also, with the same result. And if I remove the: domain setting above, then the initial session will not be overwritten, but it will not become shared either.

When I view cookies in the Cookies editor for Firefox, both subdomains use the same cookie name, but authentication is not used. This is a fairly simple user table, and I use OpenID and OAuth to authenticate with Omniauth

+7
source share
3 answers

update: the proposed solution is not so ugly, ad exchange and DSP / SSP use the same method to exchange the visitor identifier so that they can better orient the visitor with the advertisement (next time the visitor pops up into their network again)


If you can get around the cross-domain browser barrier, you can do it. For example, JSONP is specifically built for this purpose. And yes, session information is always stored centrally, otherwise, if you get a request with a zigzag session ID, how can you check if it really is?

"Those sites that authenticate with login.domain.com can use the ajax proxy or use a different method to solve the problem between domains.

The oldest "trick" is to create a hook in your application that looks like an image, since images can be downloaded everywhere.

For example, on login.domain.com you authenticate the user, go to the server and back with a response, and the cookie will be stored under the name login.domain.com with the session ID (which is also stored on the server). Then - from Javascript - you get an image with an attached session identifier, for example http://any.domain.com/path/image.jpg?sessionID=abcd → any cookies sent back in response will be stored under any.domain. com

Another solution , which is as ugly as the previous one , is to use a hidden iframe to call any.domain.com (when successful authentication occurs), this request returns a response, and its cookies will be written to any.domain. com.

If you have many subdomains, and you can complicate your architecture a bit, I highly recommend that you create a proxy server and make it available for each subdomain on the same IP address. Then no matter where the user logs in, the authentication process will always be the same for each subdomain.

+6
source

For some reason, the domain prefix with a dot did not work (rails 3.2.11) for me. To fix it, I needed 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 the request of the parent domain? ” 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.

+6
source

After you set up a Rails session for sharing on subdomains using the above line, after you are in a subdomain, you can access cookies from a domain by setting the Javascript property in your domain through your document.domain object .

Say that you are in mysubdomain.domain.com, you will set: document.domain = "domain.com"; You will now be able to access cookies from domain.com.

(Note: you cannot set document.domain in any other subdomain, due to the same origin rule)

+1
source

All Articles