¿Compartir sesión (cookies) entre subdominios en Rails?


Tengo una configuración de aplicación donde cada usuario pertenece a una empresa, y esa empresa tiene un subdominio (estoy usando subdominios de estilo basecamp). El problema al que me enfrento es que rails está creando múltiples cookies (una para lvh.me y otro para subdomain.lvh.me) que está causando un buen número de interrupciones en mi aplicación(como los mensajes de flash que son persistentes, aunque todas las solicitudes una vez iniciado sesión).

Tengo esto en mi /cofig/initilizers/session_store.archivo rb:

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

El dominio: : todo parece ser la respuesta estándar que encontré en Google, pero eso no parece funcionar para mí. Cualquier ayuda es apreciada!

Author: Wahaj Ali, 2012-05-01

7 answers

A medida que resulta 'domain: all' crea una cookie para todos los diferentes subdominios que se visitan durante esa sesión (y se asegura de que se pasen entre solicitudes). Si no se pasa ningún argumento de dominio, significa que se crea una nueva cookie para cada dominio diferente que se visita en la misma sesión y se descarta la antigua. Lo que necesitaba era una sola cookie que sea persistente durante toda la sesión, incluso cuando el dominio cambia. Por lo tanto, pasando domain: lvh.me resuelto el problemas de desarrollo. Esto crea una única cookie que permanece allí entre diferentes subdominios.

Para cualquiera que necesite más explicaciones, este es un gran enlace: http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3 /

 65
Author: Wahaj Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-23 20:31:42

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

" La parte que desea tener en cuenta aquí es que si establece: dominio = > : todo como se recomienda en algunos lugares, simplemente no funcionará a menos que estás usando localhost. : todos los valores predeterminados a una longitud de TLD de 1, que significa que si estás probando con Pow (myapp.dev) tampoco funcionará porque es un TLD de longitud 2."

En otras palabras necesidad:

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

También es una buena idea borrar tus cookies

 58
Author: montrealmike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-23 20:03:16

Estaba buscando una manera de resolver este problema sin tener que indicar explícitamente el nombre de dominio, para que pudiera saltar entre localhost, lvh.me, y los dominios que usaría en producción sin tener que seguir editando session_store.archivo rb. Sin embargo, configurar "domain: :all" no parecía estar funcionando para mí.

En última instancia, encontré que necesitaba indicar el tld_length (top level domain length) en esa expresión. El tld_length predeterminado es 1 mientras example.lvh.me tiene un tld_length de 2 y 127.0.0.1.xip.io tiene un tld_length de 5, por ejemplo. Así que lo que tenía en la session_store.archivo rb para subdominios en lvh.me en el desarrollo y cualquier otra cosa en la producción fue la siguiente.

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

Espero que esto ayude a alguien, ya que me llevó mucho tiempo encontrar esta respuesta!

 20
Author: FangedParakeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-12 11:39:04

Por alguna razón reemplazar :all con el dominio no funcionó (rails 3.2.11) para mí. Tomó un pedazo de Middleware personalizado para arreglarlo. A continuación se presenta un resumen de esa solución.

Tl; dr: Necesita escribir un Middleware de rack personalizado. Necesitas agregarlo a tu conifg/environments/[production|development].rb. Esto es on Rails 3.2.11

Las sesiones de cookies generalmente se almacenan solo para su dominio de nivel superior.

Si miras en Chrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com} Puedes ver que habrá entradas separadas para sub1.yourdomain.com y othersub.yourdomain.com y yourdomain.com

El desafío es usar el mismo archivo de almacenamiento de sesión en todos los subdominios.

Paso 1: Agregar Clase de Middleware personalizada

Aquí es donde entra Rack Middleware. Algunos recursos relevantes de rack & rails:

Aquí hay una clase personalizada que usted debe agregar en el lib Esto fue escrito por @Nader y todos deben agradecerle

# 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

Básicamente lo que esto hace es que mapeará todos los datos de su sesión de cookies en el mismo archivo de cookies que es igual a su dominio raíz.

Paso 2: Añadir A La Configuración de Rails

Ahora que tiene una clase personalizada en lib, asegúrese de que la está cargando automáticamente. Si eso no significaba nada para ti, mira aquí: Rails 3 autoload

La primera la cosa es asegurarse de que está en todo el sistema usando una tienda de cookies. En config/application.rb le decimos a Rails que use una tienda de cookies.

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

La razón por la que esto está aquí se menciona aquí es debido a la línea :domain => :all. Hay otras personas que han sugerido especificar :domain => ".yourdomain.com" en lugar de :domain => :all. Por alguna razón esto no funcionó para mí y necesitaba la clase Middleware personalizada como se describió anteriormente.

Entonces en su config/environments/production.rb añadir:

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

Nótese que el precedente dot es necesario. Consulte " ¿cookies de subdominio, enviadas en una solicitud de dominio principal?" por qué.

Entonces en su config/environments/development.rb añadir:

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

El lvh.me trick mapas en localhost. Es impresionante. Ver este Railscast sobre subdominios y esta nota para más información.

Esperemos que eso lo haga. Honestamente, no estoy del todo seguro de por qué el proceso es tan complicado, ya que siento que los sitios de subdominios cruzados son comunes. Si alguien tiene más información en las razones detrás de cada uno de estos pasos, por favor ilumínenos en los comentarios.

 16
Author: Evan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:34

Me encontré con esto mientras buscaba la forma más sencilla de configurar la cookie para que sea el dominio raíz. Parece que hay cierta información errónea sobre la opción :all cuando se pasa como la opción de dominio. Para la mayoría de los dominios, realmente funcionará como se espera, estableciendo la cookie en el dominio raíz (por ejemplo, .example.com para test.example.com). Creo que la mayoría de las personas experimentaron problemas ya que están usando el dominio lvh.me para probar. La expresión regular utilizada por rails para encontrar un dominio de nivel superior se define como DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/. Si notas la última parte, se puede ver que rails interpreta lvh.me como un TLD similar a com.au. Si su caso de uso necesita lvh.me para funcionar, entonces la opción :all no funcionará correctamente, sin embargo, parece ser la opción más simple y mejor para la mayoría de los dominios.

TL;DR, la respuesta correcta aquí, suponiendo que no se está desarrollando en un dominio de 3 letras (o cualquier dominio que confunda la expresión regular anterior) es usar :all.

 16
Author: cassanego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-16 01:43:16

¿Intentaste

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

)

Básicamente estamos diciendo tener una sola cookie para el dominio base y simplemente ignorar el subdominio..aunque este enfoque tiene algunos defectos todavía ...

 3
Author: Naveed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-01 20:03:13

Rieles 4.x (también debería estar bien con la versión Rails 5)

Cómo obtener lvh.me: 3000 y subdominio en localhost (Rails)

Simplemente, he compartido cookies para agregar .lvh.me a session_store.rb,

Se compartirá entre subdominios en localhost admin.lvh.me:3000, lvh.me:3000 y así sucesivamente...

#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
 3
Author: 7urkm3n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 11:44:52