Share session (cookies) between subdomains in Rails?

I have an application where each user belongs to a company, and this company has a subdomain (I use basecamp style subdomains). The problem I encountered is that the rails create several cookies (one for lvh.me and the other for subdomain.lvh.me), which causes quite a lot of gaps in my application (for example, flash messages are persistent, although of all requests it’s signed only once).

I have this in the file / cofig / initilizers / session _store.rb:

AppName::Application.config.session_store :cookie_store, key: '_application_devise_session', domain: :all 

Domain :: everything seems to be the standard answer I found on Google, but this does not seem to work for me. Any help is appreciated!

+76
ruby-on-rails session devise
May 01 '12 at 19:02
source share
7 answers

As it issues "domain: everything", a cookie is created for all the different subdomains that are visited during this session (and it ensures that they are passed between requests). If the domain argument is not passed, this means that a new cookie is created for every other domain that is visited in the same session, and the old one is discarded. I needed a single cookie that was persistent throughout the session, even when the domain changed. Consequently, the transition domain: lvh.me solved the development problem. This creates a single cookie that stays there between different subdomains.

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

+61
May 01 '12 at 19:46
source share

http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/

"The part that you want to pay attention to is that if you set: domain =>: everything is as recommended in some places, it just doesn’t work if you use localhost .: all the default values ​​are equal to the length of the TLD, equal to 1, which means that if you test using Pow (myapp.dev), it will not work either because it is a TLD of length 2.

In other words, you need to:

  App.config.session_store ... , :domain => :all, :tld_length => 2 

It is also recommended to clear cookies

+56
Feb 21 '13 at 18:39
source share

I was looking for a way to solve this problem without explicitly specifying a domain name, so I could jump between localhost, lvh.me and any domains that I would use in production, without the need to edit the session_store.rb file. However, setting "domain :: all" didn't seem to work for me.

I eventually found that I needed to specify tld_length (the length of the top-level domain) in this expression. By default, tld_length is 1, while example.lvh.me has tld_length 2 and 127.0.0.1.xip.io has tld_length 5, for example. So, what I had in the session_store.rb file for subdomains on lvh.me in development and otherwise in production was lower.

 MyApp::Application.config.session_store :cookie_store, key: '_MyApp_session', domain: :all, tld_length: 2 

Hope this helps someone as it took me a long time to find this answer!

+19
Nov 12 '13 at
source share

For some reason, replacing :all with a domain 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 must 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 at 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 here is mentioned here is because of 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. It's amazing. See this Railscast for subdomains and this note for more information. Information.

Hope this should do it. I honestly am 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.

+14
Feb 06 '13 at 21:59
source share

I came across this looking for the easiest way to set cookie as root domain. There seems to be some misinformation about the :all option when passed as a domain option. For most domains, it will work as expected by setting a cookie in the root domain (e.g. .example.com for test.example.com ). I think most people have experienced problems since they use the lvh.me domain for testing. The regular expression used by the rails to search for a top-level domain is defined as DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/ . If you notice the last part, you will see that the rails interpret lvh.me as a TLD, similar to com.au If your use case needs lvh.me to work, then the :all option will not work properly, however it seems to be the easiest and best option for most domains.

TL; DR, the correct answer is here if you are not working on a 3 letter domain (or any domain that confuses the above expression), you should use :all .

+14
Jul 16 '13 at 1:43 on
source share

You tried

 AppName::Application.config.session_store :cookie_store, key: '_application_devise_session', domain: 'lvh.me' 

)

Basically we say that you have a single cookie for the base domain and just ignore the subdomain. Although this approach still has some disadvantages ...

+3
May 01 '12 at 19:51
source share

Rails 4.x (should also be fine with Rails 5)

How to get lvh.mehaps000 and subdomain in localhost (Rails)

I just have common cookies to add .lvh.me to session_store.rb ,

It will be shared between subdomains on localhost admin.lvh.me:3000 , lvh.me:3000 and so on ...

 #config/initializers/session_store.rb if Rails.env.production? Rails.application.config.session_store :cookie_store, key: '_app_name_session', domain: ".domain_name.com" else Rails.application.config.session_store :cookie_store, key: '_app_name_session', domain: '.lvh.me' end 
+3
Mar 26 '17 at 1:12
source share



All Articles