web-dev-qa-db-ja.com

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

各ユーザーが会社に属しているアプリのセットアップがあり、その会社にはサブドメインがあります(ベースキャンプスタイルのサブドメインを使用しています)。私が直面している問題は、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で見つけた標準的な回答のようですが、それは私にとってはうまくいかないようです。どんな助けも大歓迎です!

84
Wahaj Ali

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

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

68
Wahaj Ali

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をクリアすることもお勧めします

61
montrealmike

ドメイン名を明示的に指定せずにこの問題を解決する方法を探していたので、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

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

21
FangedParakeet

Cookieをルートドメインに設定する最も簡単な方法を探しているときに、これに遭遇しました。ドメインオプションとして渡された場合、_:all_オプションに関する誤った情報があるようです。ほとんどのドメインでは、実際に期待どおりに機能し、Cookieをルートドメインに設定します(例:_.example.com_ for _test.example.com_)。ドメイン_lvh.me_を使用してテストしているため、ほとんどの人が問題を経験したと思います。 Railsトップレベルドメインを見つけるために使用される正規表現は、DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/と定義されます。最後の部分に注目すると、Railsは_lvh.me_を_com.au_と同様のTLDとして解釈します。ユースケースで_lvh.me_が必要な場合、_:all_オプションは正しく機能しませんが、ほとんどのドメインで最もシンプルで最適なオプションのようです。

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

16
cassanego

何らかの理由で、:allをドメインに置き換えても機能しませんでした(Rails 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.comおよびyourdomain.comに個別のエントリがあることがわかります。

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

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

これが Rackミドルウェア の出番です。関連するラック&Railsリソース:

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 Config

Libにカスタムクラスがあるので、それをオートロードするようにしてください。それがあなたにとって何の意味もない場合は、こちらをご覧ください: Rails 3 autoload

最初のことは、Cookieストアを使用してシステム全体にいることを確認することです。 config/application.rbでは、Rails Cookieストアを使用するように伝えます。

# 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 および このノート を参照してください。

うまくいけばそれでうまくいくはずです。クロスサブドメインサイトが一般的であると感じているため、このプロセスがなぜ複雑なのか、正直に完全にはわかりません。これらの各手順の背後にある理由について、さらに詳しい情報があれば、コメントで教えてください。

16
Evan

Rails 4.x(Rails 5 version)でも問題ないはずです)

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

単純に、追加する.lvh.me into session_store.rb

ローカルホスト上のサブドメイン間で共有されますadmin.lvh.me:3000lvh.me:3000 等々...

#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
4
7urkm3n

試しましたか

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

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

3
Naveed

rails5をサポート

任意のドメインで動作するようにしたい場合:

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
cgg5207