Поделиться сессией (cookies) между поддоменами в Rails?


У меня есть настройка приложения, где каждый пользователь принадлежит компании, и эта компания имеет поддомен (я использую поддомены стиля basecamp). Проблема, с которой я сталкиваюсь, заключается в том, что rails создает несколько файлов cookie (один для lvh.me и еще один для subdomain.lvh.me) что вызывает довольно много перерывов в моем приложении (например, флэш-сообщения являются постоянными, хотя все запросы после входа в систему).

У меня есть это в моем /cofig/initilizers/session_store.рубидий файл:

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

домен:: все, кажется, стандартный ответ, который я нашел в Google, но это, похоже, не работает для меня. Любая помощь приветствуется!

7 80

7 ответов:

как оказалось, "домен: все" создает файл cookie для всех различных поддоменов, которые посещаются во время этого сеанса (и это гарантирует, что они передаются между запросами). Если аргумент домена не передается, это означает, что новый файл cookie создается для каждого другого домена, который посещается в том же сеансе, а старый удаляется. Мне нужен был один файл cookie, который сохраняется на протяжении всего сеанса, даже когда домен изменений. Следовательно, проходя domain: lvh.me решена проблема в развитии. Это создает один файл cookie, который остается между разных поддоменов.

для тех, кто нуждается в дальнейших объяснениях, это отличная ссылка: http://excid3.com/blog/sharing-a-devise-user-session-across-subdomains-with-rails-3/

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

" часть, которую вы хотите следить за здесь является то, что если вы установите: домен => :все, как рекомендуется в некоторых местах, он просто не будет работать, если вы используете localhost. :все значения по умолчанию имеют длину TLD 1, которая означает, если вы тестируете с Pow (myapp.dev) это тоже не сработает потому что это TLD длины 2."

другими словами, вы нужно:

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

также хорошая идея, чтобы очистить cookies

Я искал способ решить эту проблему без необходимости явно указывать доменное имя, чтобы я мог прыгать между localhost, lvh.me, и какие бы Домены я ни использовал в производстве без необходимости продолжать редактировать session_store.rb файл. Однако настройка "domain:: all", похоже, не работала для меня.

в конечном счете я обнаружил, что мне нужно указать tld_length (длина домена верхнего уровня) в этом выражении. Значение по умолчанию tld_length равно 1 while example.lvh.me имеет a tld_length из 2 и 127.0.0.1.xip.io имеет tld_length 5, например. Так что у меня было в session_store.rb файл для поддоменов на lvh.me в разработке и все остальное в производстве было ниже.

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

надеюсь, это поможет кому-то, так как мне потребовалось много времени, чтобы найти этот ответ!

почему-то заменив :all с доменом у меня не получилось (рельсы 3.2.11). Для его исправления потребовался кусок пользовательского промежуточного программного обеспечения. Краткое изложение этого решения приводится ниже.

tl; dr: вам нужно написать пользовательское промежуточное программное обеспечение стойки. Вам нужно добавить его в свой conifg/environments/[production|development].rb. Это на рельсах 3.2.11

сеансы Cookie обычно хранятся только для вашего домена верхнего уровня.

если вы посмотрите в Chrome -> Settings -> Show advanced settings… -> Privacy/Content settings… -> All cookies and site data… -> Search {yourdomain.com} вы можете видеть, что там будет отдельные записи для sub1.yourdomain.com и othersub.yourdomain.com и yourdomain.com

задача состоит в том, чтобы использовать один и тот же файл хранилища сеансов во всех поддоменах.

Шаг 1: Добавьте Пользовательский Класс Промежуточного Программного Обеспечения

вот тут Rack Middleware приходит. Некоторые соответствующие стойки и рельсы ресурсы:

вот пользовательский класс, который вы должны добавить в 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: Добавить В Рельсы Конфигурации

теперь, когда у вас есть пользовательский класс в 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. По какой-то причине это не сработало для меня, и мне нужен был пользовательский класс Middleware, как описано выше.

затем в 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 о поддоменах и эта заметка для получения дополнительной информации.

надеюсь, что это должно сделать это. Я честно не совсем уверен, почему этот процесс является таким запутанным,поскольку я чувствую, что перекрестные поддомены являются общими. Если у кого-то есть какие-либо дополнительные идеи о причинах каждого из этих шагов, пожалуйста, просветите нас в комментариях.

я наткнулся на это, ища самый простой способ установить cookie в качестве корневого домена. Кажется, есть некоторая дезинформация о :all опция при передаче в качестве опции домена. Для большинства доменов он будет работать так, как ожидалось, установив cookie в корневой домен (например,.example.com на test.example.com). Я думаю, что большинство людей испытывали проблемы, так как они используют домен lvh.me чтобы проверить. Регулярное выражение, используемое rails для поиска домена верхнего уровня, определяется как DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/. Если вы обратите внимание на последнюю часть, вы можете видеть, что rails интерпретирует lvh.me как TLD похож на com.au. Если ваш вариант использования нуждается lvh.me до :all опция не будет работать должным образом, однако, это, кажется, самый простой и лучший вариант для большинства доменов.

TL; DR, правильный ответ здесь, предполагая, что вы не развиваетесь на 3-буквенном домене (или любом домене, который путает вышеуказанное регулярное выражение), должен использовать :all.

ты

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

)

в основном, мы говорим, что есть один cookie для домена и просто игнорировать поддомен..хотя этот подход имеет некоторые недостатки до сих пор ...

рельсы 4.x (также должно быть хорошо с рельсами 5 версии)

Как получить lvh. me:3000 и поддомен в localhost (Rails)

просто, я поделился куки для добавления .lvh.me на session_store.rb,

он будет разделен между поддоменами на localhost admin.lvh.me:3000,lvh.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