web-dev-qa-db-fra.com

Que fait Rails 3 domaine session_store: tout fait vraiment?

Question mise à jour pour la rendre plus claire

Je comprends que vous pouvez définir le domaine de votre session_store pour partager des sessions entre des sous-domaines comme ceci: Rails.application.config.session_store :cookie_store, :key => '_my_key', :domain => "mydomain.com"

in Rails 3, quel est le paramètre :domain => :all faire? Il ne peut pas vous permettre de partager des sessions sur des domaines de premier niveau, les cookies ne peuvent pas le faire. La documentation indique qu'elle suppose un domaine de premier niveau. Que se passe-t-il si plusieurs domaines accèdent à votre application?

Dans mon application, mes utilisateurs peuvent créer des sous-domaines personnels d'un domaine principal, mais peuvent également accéder à ce sous-domaine via leur propre domaine personnalisé.

Quel est le paramètre de domaine session_store correct pour que je puisse: a) partager des sessions sur tous les domaines de mon domaine principal, par exemple "mydomain.com" b) les utilisateurs qui accèdent à leur sous-domaine personnel, par exemple "user1.mydomain.com" via un CNAME personnalisé Une URL comme "some.otherdomain.com" peut toujours créer des sessions distinctes.

Merci

57
Nader

OK, la façon de procéder consiste à définir dynamiquement le domaine sur le cookie de session. Pour ce faire suffisamment tôt, il faut le faire en tant que middleware de rack:

# 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
33
Nader

Je ne pensais pas que les réponses existantes répondaient directement à la question dans le titre, donc je voulais apporter ma contribution.

Lorsque le client (navigateur) accède à un site Web, le site Web indique au client de définir un cookie. Dans ce cas, il spécifie le nom, la valeur, le domaine et le chemin du cookie.

:domain => :all indique Rails pour placer un point devant le domaine des cookies (qui est l'hôte que votre navigateur a parcouru), de sorte que le cookie s'applique à tous les sous-domaines.

Voici le code pertinent de Rails 4.1 (actionpack/lib/action_dispatch/middleware/cookies.rb):

  def handle_options(options) #:nodoc:
    options[:path] ||= "/"

    if options[:domain] == :all
      # if there is a provided tld length then we use it otherwise default domain regexp
      domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP

      # if Host is not ip and matches domain regexp
      # (ip confirms to domain regexp so we explicitly check for ip)
      options[:domain] = if (@Host !~ /^[\d.]+$/) && (@Host =~ domain_regexp)
        ".#{$&}"
      end
    elsif options[:domain].is_a? Array
      # if Host matches one of the supplied domains without a dot in front of it
      options[:domain] = options[:domain].find {|domain| @Host.include? domain.sub(/^\./, '') }
    end
  end

Je vois que vous avez déjà répondu à la deuxième partie de votre question sur l'autorisation de sous-domaines pour avoir des sessions distinctes.

19
Tyler Collier

tl; dr: Utilisez le code de @ Nader . MAIS j'ai trouvé que je devais l'ajouter dans mon conifg/environments/[production|development].rb et passez mon domaine à préfixe de point comme argument. C'est sur Rails 3.2.11

Les sessions de cookies sont généralement stockées uniquement pour votre domaine de premier niveau.

Si vous regardez dans 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 distinctes pour sub1.yourdomain.com et othersub.yourdomain.com et yourdomain.com

Le défi consiste à utiliser le même fichier de stockage de session sur tous les sous-domaines.

Étape 1: utilisez le code CustomDomainCookie de @ Nader

C'est là qu'intervient Rack Middleware . Quelques ressources plus pertinentes et Rails:

Fondamentalement, cela permet de mapper toutes vos données de session de cookies sur le même fichier de cookies identique à votre domaine racine.

Étape 2: ajouter à Rails Config

Maintenant que vous avez une classe personnalisée dans lib, assurez-vous de la charger automatiquement. Si cela ne vous dit rien, regardez ici: Rails 3 autoload

La première chose est de vous assurer que vous êtes à l'échelle du système en utilisant un magasin de cookies. Dans config/application.rb nous demandons à Rails d'utiliser un magasin de cookies.

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

La raison pour laquelle ceci est ici est mentionnée ici en raison du :domain => :all ligne. Il y a d'autres personnes qui ont suggéré de spécifier :domain => ".yourdomain.com" au lieu de :domain => :all. Pour une raison quelconque, cela n'a pas fonctionné pour moi et j'avais besoin de la classe Middleware personnalisée comme décrit ci-dessus.

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

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

Notez que le point précédent est nécessaire. Voir " cookies de sous-domaine, envoyés dans une demande de domaine parent? " pour savoir pourquoi.

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

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

L'astuce lvh.me est mappée sur localhost. C'est génial. Voir ce Railscast sur les sous-domaines et cette note pour plus d'informations.

J'espère que cela devrait le faire. Honnêtement, je ne sais pas vraiment pourquoi le processus est si compliqué, car je pense que les sites de sous-domaines croisés sont courants. Si quelqu'un a d'autres informations sur les raisons de chacune de ces étapes, veuillez nous éclairer dans les commentaires.

12
Evan

Cette option est utilisée pour s'assurer que l'application pourra partager des sessions entre les sous-domaines. L'option: all suppose que notre application a une taille de domaine de premier niveau de 1. Sinon, nous pouvons spécifier un nom de domaine à la place et qui sera utilisé comme domaine de base pour la session.

10
Rishav Rastogi

Hmmm,

Je déploie une application hébergée sous www.xyz.com et sous xyz.com.

Pour moi,: domain =>: all définit le domaine du cookie de session sur xyz.com. Donc pas pour un domaine de premier niveau mais pour 1 niveau au dessus du tld.

Jan Willem

1
Jan Willem Luiten