wake-up-neo.com

Sitzung (Cookies) zwischen Subdomains in Rails freigeben?

Ich habe ein App-Setup, bei dem jeder Benutzer zu einer Firma gehört und diese Firma eine Subdomain hat (ich verwende Basecamp-Style-Subdomains). Das Problem, mit dem ich konfrontiert bin, ist, dass Rails mehrere Cookies erstellt (eines für lvh.me und eines für subdomain.lvh.me), was zu einigen Unterbrechungen in meiner Anwendung führt (z. B. dass Flash-Nachrichten alle Anfragen einmalig durchgängig machen angemeldet).

Ich habe folgendes in meiner /cofig/initilizers/session_store.rb -Datei:

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

Die Domain: Alles scheint die Standardantwort zu sein, die ich bei Google gefunden habe, aber das scheint für mich nicht zu funktionieren. Jede Hilfe wird geschätzt! 

81
Wahaj Ali

Da es sich nicht um die Domäne "all:" handelt, wird ein Cookie für alle verschiedenen Subdomains erstellt, die während dieser Sitzung besucht werden (und es wird sichergestellt, dass sie zwischen den Anforderungen weitergegeben werden). Wenn kein Domänenargument übergeben wird, bedeutet dies, dass für jede andere Domäne, die in derselben Sitzung besucht wird, ein neuer Cookie erstellt wird und der alte gelöscht wird. Was ich brauchte, war ein einzelner Cookie, der auch während der Sitzung bestehen bleibt, selbst wenn sich die Domäne ändert. Durch domain: "lvh.me" wurde das Problem in der Entwicklung gelöst. Dadurch wird ein einzelner Cookie erstellt, der zwischen verschiedenen Subdomains verbleibt.

Für alle, die weitere Erklärungen benötigen, ist dies ein hervorragender Link: http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-Rails-3/

66
Wahaj Ali

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

"Der Teil, auf den Sie achten sollten, ist, dass, wenn Sie Folgendes festlegen: domain => : All like is in einigen Orten empfohlen wird, es nicht funktionieren wird, es sei denn, Sie verwenden localhost auf eine TLD-Länge von 1, was .__ bedeutet, wenn Sie mit Pow (myapp.dev) testen, wird es auch nicht funktionieren Dies ist eine TLD der Länge 2. "

Mit anderen Worten: Sie brauchen:

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

Auch eine gute Idee, um Ihre Cookies zu löschen

58
montrealmike

Ich suchte nach einer Möglichkeit, dieses Problem zu lösen, ohne den Domänennamen explizit angeben zu müssen. Daher konnte ich zwischen localhost, lvh.me und den Domains wechseln, die ich in der Produktion verwenden würde, ohne die session_store.rb-Datei bearbeiten zu müssen. Die Einstellung "Domäne: Alle" schien jedoch nicht für mich zu funktionieren.

Letztendlich stellte ich fest, dass ich die tld_length (Länge der obersten Domäne) in diesem Ausdruck angeben musste. Der Standardwert für tld_length ist 1, während example.lvh.me eine tld_length von 2 und 127.0.0.1.xip.io eine tld_length von beispielsweise 5 hat. Was ich also in der session_store.rb-Datei für Subdomains auf lvh.me in Entwicklung hatte und was sonst noch in der Produktion war, war das Folgende.

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

Ich hoffe, das hilft jemandem, da ich lange gebraucht habe, um diese Antwort zu finden!

20
FangedParakeet

Ich bin darauf gestoßen, als ich nach dem einfachsten Weg suchte, den Cookie als Stammdomäne festzulegen. Es scheint, dass es falsche Informationen über die :all-Option gibt, wenn sie als Domain-Option übergeben werden. Für die meisten Domänen funktioniert es tatsächlich wie erwartet und setzt das Cookie auf die Stammdomäne (z. B. .example.com für test.example.com). Ich denke, dass die meisten Leute Probleme hatten, seit sie die Domain lvh.me zum Testen verwenden. Der von Rails zum Suchen einer Top-Level-Domäne verwendete Regex ist als DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/ definiert. Wenn Sie den letzten Teil beachten, können Sie sehen, dass Rails lvh.me als eine TLD interpretiert, die com.au ähnlich ist. Wenn für Ihren Anwendungsfall lvh.me erforderlich ist, funktioniert die :all-Option nicht ordnungsgemäß. Es scheint jedoch für die meisten Domänen die einfachste und beste Option zu sein.

TL; DR, die richtige Antwort hier, vorausgesetzt, Sie entwickeln nicht auf einer 3-Buchstaben-Domäne (oder einer Domäne, die den obigen Regex verwirrt), :all.

16
cassanego

Aus irgendeinem Grund funktionierte das Ersetzen von :all durch die Domäne (Rails 3.2.11) für mich nicht. Es brauchte ein Stück benutzerdefinierte Middleware, um das Problem zu beheben. Eine Zusammenfassung dieser Lösung finden Sie unten.

tl; dr: Sie müssen eine benutzerdefinierte Rack-Middleware schreiben. Sie müssen es in Ihren conifg/environments/[production|development].rb einfügen. Dies ist auf Rails 3.2.11

Cookie-Sitzungen werden normalerweise nur für Ihre Top-Level-Domain gespeichert.

Wenn Sie in Chrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com} suchen, können Sie sehen, dass separate Einträge für sub1.yourdomain.com und othersub.yourdomain.com und yourdomain.com vorhanden sind.

Die Herausforderung besteht darin, in allen Unterdomänen dieselbe Sitzungsspeicherdatei zu verwenden.

Schritt 1: Fügen Sie eine benutzerdefinierte Middleware-Klasse hinzu

Hier kommt Rack Middleware zum Einsatz. Einige relevante Rack & Rails-Ressourcen:

Hier ist eine benutzerdefinierte Klasse, die Sie in die libeinfügen sollten. Diese wurde von @Nader geschrieben und Sie sollten sich bei ihm bedanken.

# 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

Im Prinzip werden dabei alle Ihre Cookie-Sitzungsdaten auf dieselbe Cookie-Datei abgebildet, die Ihrer Stammdomäne entspricht.

Schritt 2: Hinzufügen zu Rails Config

Jetzt, da Sie eine benutzerdefinierte Klasse in lib haben, stellen Sie sicher, dass sie automatisch geladen wird. Wenn dir das nichts bedeutete, schau hier: Rails 3 autoload

Als Erstes müssen Sie sicherstellen, dass Sie systemweit einen Cookie-Store verwenden. In config/application.rb weisen wir Rails an, einen Cookie-Store zu verwenden.

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

Der Grund, warum dies hier erwähnt wird, liegt an der :domain => :all-Zeile. Es gibt andere Personen, die vorgeschlagen haben, :domain => ".yourdomain.com" anstelle von :domain => :all anzugeben. Aus irgendeinem Grund funktionierte das nicht für mich und ich brauchte die benutzerdefinierte Middleware-Klasse wie oben beschrieben.

Dann füge in deinem config/environments/production.rb hinzu:

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

Beachten Sie, dass der vorangehende Punkt erforderlich ist. Siehe " Sub-Domain-Cookies, die in einer übergeordneten Domain-Anfrage gesendet wurden ", warum.

Dann füge in deinem config/environments/development.rb hinzu:

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

Der lvh.me-Trick wird auf localhost abgebildet. Es ist toll. Siehe diesen Railscast über Subdomains und diesen Hinweis für weitere Informationen.

Hoffentlich sollte es das tun. Ich bin ehrlich gesagt nicht ganz sicher, warum der Prozess so kompliziert ist, da ich denke, dass Subdomain-Websites häufig sind. Wenn jemand weitere Einsichten in die Gründe hinter diesen Schritten hat, informieren Sie uns bitte in den Kommentaren.

16
Evan

Rails 4.x (sollte auch mit Rails 5-Version in Ordnung sein)

Wie bekomme ich lvh.me:3000 und subdomain in localhost (Rails)

Ich habe einfach Cookies zum Hinzufügen von .lvh.me zu session_store.rb freigegeben, 

Es wird zwischen Subdomains auf localhost admin.lvh.me:3000, lvh.me:3000 und so weiter geteilt ...

#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

Hast du versucht 

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

)

im Grunde sagen wir, dass wir ein einzelnes Cookie für die Basisdomäne haben und die Subdomain einfach ignorieren. Obwohl dieser Ansatz noch einige Mängel aufweist ... 

3
Naveed

unterstützung Rails5

wenn Sie möchten, funktioniert es mit jeder Domain:

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

Zur Konfiguration pro Umgebung können Sie Folgendes verwenden:

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

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

0
cgg5207