Railsのサブドメイン間でセッション(Cookie)を共有しますか?


92

各ユーザーが会社に属しているアプリのセットアップがあり、その会社にはサブドメインがあります(私はベースキャンプスタイルのサブドメインを使用しています)。私が直面している問題は、railsが複数のcookie(lvh.me用とsubdomain.lvh.me用)を作成し、アプリケーションでかなりの数の中断を引き起こしていることです(フラッシュメッセージがすべての要求に対して一度永続化されるなど)サインイン)。

これは/cofig/initilizers/session_store.rbファイルにあります。

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

ドメイン::allはGoogleで見つけた標準的な回答のようですが、それは私にとってはうまくいかないようです。どんな助けでもありがたいです!

回答:


74

判明したように、「ドメイン:すべて」は、そのセッション中にアクセスされるすべての異なるサブドメインのCookieを作成します(リクエスト間でパススルーされることを保証します)。ドメイン引数が渡されない場合、同じセッションでアクセスされる異なるドメインごとに新しいCookieが作成され、古いCookieは破棄されます。私が必要としたのは、ドメインが変更された場合でも、セッション全体を通じて永続的な単一のCookieでした。したがって、合格するdomain: "lvh.me"と開発の問題が解決しました。これにより、異なるサブドメイン間に存在する単一のCookieが作成されます。

詳細な説明が必要な人にとって、これは素晴らしいリンクです:http : //excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/


2
ありがとうDude ..私は自分のプロジェクトの1つでこの問題に直面してきました。最後に解決策を見つけました..
Shirjeel Alam

3
config.secret_key_baseすべてのアプリケーションで同じものを使用してください。そうしないと、Cookieをデコードできません。
Bruno Buccolo 2014年

5
これに関連するRails 4に関する質問はありません。これが変更されたかどうかをご存知ですか。プロジェクトで使用できません。それはクッキーを作り直し続けます。ありがとう。
アンディ

CacheStorememcachedにセッションを格納するために使用したい場合はどうなりますか?
Amit Patel

2
Rails4で、私はこれが唯一のアンダースコアをダッシュでサブドメインのために働いたがないことがわかった:Appname::Application.config.session_store :cookie_store, key: '_appname_session', domain: :all, tld_length: 2
user1515295

68

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

「ここで注意したいのは、一部の場所で:domain =>:all likeを設定すると、localhostを使用しない限り機能しないことです。:allのデフォルトはTLDの長さ1です、つまり、Pow(myapp.dev)でテストしている場合、長さ2のTLDであるため、機能しません。」

つまり、次のものが必要です。

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

また、Cookieをクリアすることをお勧めします


1
1つの変更がすべての環境(app.comおよびapp.dev)で機能するため、これが最良の答えです。カスタムミドルウェアは必要ありません。クッキーをクリアするのも良い点です!
Turadg 2013

1
欠けている, :tld_length => 2
モントリオールマイク2014年

1
config.secret_key_baseすべてのアプリケーションで同じものを使用してください。そうしないと、Cookieをデコードできません。
Bruno Buccolo 2014年

4
:domain => :allRails 4では機能しませんdomain => 'lvh.me', tld_length = 2。それは私のために働きました
Minh

1
Rails 4.2をdomain: :all, tld_length: 2使用すると、lvh.meドメインを使用しているときに良い結果が得られました。
zwippie 2015年

24

私はドメイン名を明示的に述べる必要なしにこの問題を解決する方法を探していたので、localhost、lvh.me、およびsession_store.rbファイルを編集し続ける必要なしに本番環境で使用するドメイン間を行き来できました。しかし、「domain::all」を設定してもうまくいかないようです。

最終的に、その式でtld_length(トップレベルのドメイン長)を指定する必要があることがわかりました。デフォルトのtld_lengthは1ですが、example.lvh.meのtld_lengthは2で、127.0.0.1.xip.ioのtld_lengthは5です。したがって、開発中のlvh.meのサブドメイン用のsession_store.rbファイルに含まれていたものと、本番環境の他のすべてのものは以下のとおりでした。

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

この答えを見つけるのに長い時間がかかったので、これが誰かの役に立つことを願っています!


19

何らかの理由:allで、ドメインへの置き換えが機能しませんでした(レール3.2.11)。それを修正するには、カスタムミドルウェアが必要でした。そのソリューションの概要は以下のとおりです。

tl; dr:カスタムのラックミドルウェアを作成する必要があります。に追加する必要がありますconifg/environments/[production|development].rb。これはRails 3.2.11にあります

Cookieセッションは通常、トップレベルドメインでのみ保存されます。

調べてみると、と、およびにChrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com}個別のエントリがあることがわかります。sub1.yourdomain.comothersub.yourdomain.comyourdomain.com

課題は、すべてのサブドメインで同じセッションストアファイルを使用することです。

ステップ1:カスタムミドルウェアクラスを追加する

これが、Rack Middlewareの出番です。関連するラックとレールのリソース:

ここではあなたが追加する必要があることカスタムクラスであるlib によって書かれたこの@Naderは、あなたのすべては彼に感謝すべきです

# 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

基本的にこれが行うことは、すべてのCookieセッションデータを、ルートドメインと等しいまったく同じCookieファイルにマップして戻すことです。

ステップ2:Rails設定に追加する

libにカスタムクラスがあるので、それをオートロードしていることを確認してください。それがあなたにとって何の意味もないなら、ここを見てください:Rails 3 autoload

最初に、Cookieストアを使用してシステム全体にアクセスできるようにします。ではconfig/application.rb、Cookieストアを使用するようにRailsに指示します。

# We use a cookie_store for session data
config.session_store :cookie_store,
                     :key => '_yourappsession',
                     :domain => :all

これがここにある理由はここに記載されているためです:domain => :all。の:domain => ".yourdomain.com"代わりに指定することを提案した他の人々がいます:domain => :all。何らかの理由でこれはうまくいかず、上記のカスタムミドルウェアクラスが必要でした。

次に、あなたのconfig/environments/production.rb追加で:

config.middleware.use "CustomDomainCookie", ".yourdomain.com"

前のドットが必要であることに注意してください。理由については、「親ドメインリクエストで送信されたサブドメインCookieについて」をご覧ください。

次に、あなたのconfig/environments/development.rb追加で:

config.middleware.use "CustomDomainCookie", ".lvh.me"

lvh.meトリックはlocalhostにマップします。それは素晴らしいです。詳細については、サブドメインに関するこのRailscastこのメモを参照してください。

うまくいけば、それでうまくいくでしょう。クロスサブドメインのサイトが一般的だと思うので、私は正直に言って、プロセスがこれほど複雑である理由を完全に確信していません。これらの各手順の背後にある理由について誰かがさらに洞察を持っている場合は、コメントで教えてください。


複数のトップレベルドメインでこれを機能させる方法はありますか?さまざまな国で動作する製品を持っています。ここでは、デフォルトのドメインがyourdomain.comであると想定していますが、.be .sv .fr .com.br .com.arなどで機能すると想定した場合はどうなりますか?ありがとう。
Marc Lainez 2013

これを機能させることができません。私はrails 4で開発していますが、rialsは上記のすべてのコードを穏やかに無視しているようです。サブドメイン間でセッションを共有したくないだけです。
Ole HenrikSkogstrøm2013年

@OleHenrikSkogstrøm config.secret_key_baseすべてのアプリケーションで同じものを使用してください。そうしないと、Cookieをデコードできません。
Bruno Buccolo 2014年

17

Cookieをルートドメインに設定する最も簡単な方法を探しているときに、これに遭遇しました。:allドメインオプションとして渡されたときに、オプションに関する誤った情報があるようです。予想通りほとんどのドメインでは、それは実際に(たとえば、ルートドメインにクッキーを設定し、動作する.example.comためtest.example.com)。lvh.meテストにドメインを使用しているため、ほとんどの人が問題を経験したと思います。Railsがトップレベルドメインを見つけるために使用する正規表現は、と定義されていますDOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/。最後の部分に注目すると、railsがとlvh.me同様のTLDとして解釈されることがわかりますcom.au。ユースケースが機能lvh.meする必要がある場合、:allオプションは適切に機能しませんが、ほとんどのドメインにとって最もシンプルで最良のオプションのようです。

TL; DR、ここでの正しい答えは、3文字のドメイン(または上記の正規表現と混同するドメイン)で開発していないと仮定すると、を使用すること:allです。


ありがとうございました。これにより、なぜ多くの回答がtld_lengthに2を推奨していたのか、なぜ私がそうする必要がなかったのかを理解するのに役立ちました。
スープドッグ

この答えはもっと高くする必要があります。ありがとうございます。
luca.busin

「com.auに類似したTLDとしてのlvh.me」BTW Railsは、確かに.meを国のドメイン(モンテネグロ)でもあるのと同じ方法で解釈する必要があります。
mahemoff

7

Rails 4.x(Rails 5/6バージョンでも問題ありません)

localhost(Rails)でlvh.me:3000とサブドメインを取得する方法

開発:私は追加するためにクッキーを共有している.lvh.mesession_store.rb

localhost admin.lvh.me:3000などのサブドメイン間で共有さlvh.me:3000れます...

#config/initializers/session_store.rb

domain = Rails.env.production? ? ".domain_name.com" : ".lvh.me"

Rails.application.config.session_store :cookie_store, 
                      key: '_app_name_session', domain: domain

4

試しましたか

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

基本的には、ベースドメインに単一のCookieを設定し、サブドメインを無視するだけです。ただし、このアプローチにはまだいくつかの欠陥があります...


1

サポートレール5

任意のドメインで機能する場合:

Rails.application.config.session_store :cookie_store, key: '_my_app_session', domain: :all, tld_length: 2

環境ごとに構成するには、以下を使用できます。

Rails.application.config.session_store :cookie_store, key: '_my_app_session', domain: {
  production: '.example.com',
  development: '.example.dev'
}.fetch(Rails.env.to_sym, :all)

参照:https : //github.com/plataformatec/devise/wiki/How-To : -Use-subdomains


0

セッションストアにRedisを使用している場合。

if Rails.env.development?
    Rails.application.config.session_store :redis_store, {
       servers: [
        { host: 'localhost', port: 6379},
      ],
      key: '_app_session',
      expire_after: 1.day,
      domain: :all
    }

else
    Rails.application.config.session_store :redis_store, {
       servers: [
        { host: HOST_URL, port: PORT},
      ],
      key: '_app_session',
      expire_after: 1.day,
      domain: '.domain.com',
      tld_length: 2
    }
    
end 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.