100 votes

Partager une session (cookies) entre sous-domaines dans Rails?

J'ai une application de configuration où chaque utilisateur appartient à une entreprise et que l'entreprise a un sous-domaine (je l'utilise basecamp style des sous-domaines). Le problème que je suis confronté est que rails est de créer plusieurs cookies (un pour l'hvg.moi et un autre pour le sous-domaine.hvg.moi) qui est à l'origine de tout à fait quelques pauses dans mon application(tels que des messages flash insiste bien sur toutes les demandes une fois connecté).

J'ai cela dans mon /cofig/initilizers/session_store.rb fichier:

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

Le domaine: tous semble être le type de réponse que j'ai trouvé sur Google, mais ça ne semble pas fonctionner pour moi. Toute aide est appréciée!

81voto

Wahaj Ali Points 1897

Il se trouve que les aboutissants de domaine: tous les " crée un cookie pour tous les différents sous-domaines qui sont visités au cours de la session (et il s'assure qu'ils sont passés entre la demande). Si aucun domaine argument est passé, cela signifie qu'un nouveau cookie est créé pour chaque domaine qui est visité dans la même session et l'ancien est rejeté. Ce que j'avais besoin d'un seul cookie persistant tout au long de la session, même lorsque le domaine des changements. Par conséquent, passant de domaine: hvg.moi " a résolu le problème dans le développement. Cela crée un cookie qui reste-t-il entre les différents sous-domaines.

Pour toute personne ayant besoin de plus d'explications, c'est un grand lien: http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/

72voto

montrealmike Points 3795

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

"La partie que vous voulez regarder dehors pour, c'est que si vous définissez :domaine => :tout comme vous conseillons dans certains endroits, il ne fonctionnera pas à moins que vous utilisez localhost. :toutes les valeurs par défaut pour un TLD longueur de 1, ce qui signifie que si vous faites des tests avec Pow (myapp.dev) il ne fonctionne pas, soit parce que c'est un TLD de longueur 2."

En d'autres mots, vous avez besoin de:

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

Aussi une bonne idée d'effacer vos cookies

26voto

FangedParakeet Points 56

J'étais à la recherche d'un moyen de résoudre ce problème sans avoir à mentionner explicitement le nom de domaine, afin que je puisse hop entre localhost, hvg.moi, et quels que soient les domaines que je voudrais utiliser dans la production sans avoir à retravailler le session_store.rb fichier. Toutefois, le paramètre "domaine :tous" ne semble pas fonctionner pour moi.

En fin de compte j'ai trouvé que j'avais besoin de l'état de la tld_length (domaine de premier niveau de la longueur) dans cette expression. La valeur par défaut tld_length est de 1 bien que l'exemple.hvg.m'a un tld_length de 2 et 127.0.0.1.xip.io a un tld_length de 5, par exemple. Donc, ce que j'avais dans la session_store.rb fichier de sous-domaines sur hvg.m'en développement et tout le reste de la production est le ci-dessous.

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

Espérons que cela aide quelqu'un, qu'il m'a fallu du temps pour trouver cette réponse!

19voto

Evan Points 1850

Pour une raison quelconque remplacement d' :all avec le domaine ne fonctionne pas (rails 3.2.11) pour moi. Il a pris un morceau de la coutume, Middleware pour le fixer. Un résumé de cette solution est ci-dessous.

tl;dr: Vous avez besoin d'écrire une coutume Middleware Rack. Vous devez l'ajouter dans votre conifg/environments/[production|development].rb. C'est sur des Rails 3.2.11

Les cookies de session sont stockés uniquement pour votre domaine de premier niveau.

Si vous regardez en Chrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com} Vous pouvez voir qu'il y aura des entrées séparées pour sub1.yourdomain.com et othersub.yourdomain.com et yourdomain.com

Le défi consiste à utiliser la même session de stocker des fichiers dans tous les sous-domaines.

Étape 1: Ajouter Des Middleware De Classe

C'est là Middleware Rack . Quelques rack & rails de ressources:

Voici une classe personnalisée qui vous convient d'ajouter dans l' lib Ceci a été écrit par @Nader et vous devriez tous le remercier

# 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

Fondamentalement, ce que ce n'est qu'il sera de cartographier l'ensemble des votre cookie de session des données sur exactement le même fichier cookie qui est égal à la racine de votre domaine.

Étape 2: Ajouter Des Rails Config

Maintenant que vous avez une classe personnalisée dans lib, assurez-vous sont auto-chargement. Si cela ne signifiait rien pour vous, regardez ici: Rails 3 autoload

La première chose est de s'assurer que vous êtes à l'échelle du système à l'aide d'une banque de cookies. En config/application.rb nous raconter des Rails d'installation d'un cookie magasin.

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

La raison de ce qui est ici est ici mentionné est à cause de l' :domain => :all ligne de. Il y a d'autres gens qui ont suggéré à spécifier :domain => ".yourdomain.com" au lieu de :domain => :all. Pour une raison quelconque, cela ne fonctionne pas pour moi et j'avais besoin de la coutume Middleware classe comme décrit ci-dessus.

Puis dans votre config/environments/production.rb ajouter:

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

Notez que le point est nécessaire. Voir "sous-domaine "cookies", envoyés dans un domaine parent demande?" pour pourquoi.

Puis dans votre config/environments/development.rb ajouter:

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

L'hvg.moi le truc de cartes sur localhost. C'est génial. Voir ce Railscast sur les sous-domaines et cette remarque pour plus d'info.

Normalement ça devrait le faire. Honnêtement, je ne suis pas entièrement sûr de savoir pourquoi le processus est ce alambiqué, comme je me sens sous-domaine de la croix des sites sont communs. Si quelqu'un a des idées sur les raisons de chacune de ces étapes, éclaire-nous dans les commentaires.

19voto

cassanego Points 136

Je suis tombé sur ce alors que la recherche de la façon la plus simple de définir le cookie à la racine du domaine. Il semble qu'il y ait certains la désinformation à propos de l' :all option lorsqu'elle est transmise comme l'option domaine. Pour la plupart des domaines, il va fonctionner comme prévu, le réglage du cookie à la racine du domaine (par exemple, .example.com pour test.example.com). Je pense que la plupart des gens expérimenté des problèmes depuis qu'ils utilisent le domaine lvh.me de test. L'expression régulière utilisée par les rails de trouver un domaine de premier niveau est défini pour être DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/. Si vous notez que la dernière partie, vous pouvez voir que les rails interprète lvh.me comme TLD similaire com.au. Si votre cas d'utilisation, les besoins en lvh.me de travail, puis l' :all option ne fonctionnera pas correctement, cependant, elle semble être la plus simple et la meilleure option pour la plupart des domaines.

TL;DR, la bonne réponse ici, en supposant que vous n'êtes pas sur un 3 lettre de domaine (ou tout autre domaine qui confond ci-dessus regex) est d'utiliser :all.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X