Разделить сеанс (куки) между субдоменами в Rails?

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

У меня это в файле /cofig/initilizers/session _store.rb:

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

Также рекомендуется очистить файлы cookie

Ответ 3

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

В конечном итоге я обнаружил, что мне нужно указать tld_length (длина домена верхнего уровня) в этом выражении. По умолчанию tld_length равно 1, тогда как example.lvh.me имеет 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

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

Ответ 4

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

tl; dr: Вам нужно написать собственное промежуточное ПО Rack. Вы должны добавить его в свой conifg/environments/[production|development].rb. Это находится на Rails 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 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: Добавить в Rails Config

Теперь, когда у вас есть пользовательский класс в lib, убедитесь, что он автоматически загружает его. Если это ничего не значит для вас, посмотрите здесь: Автозагрузка Rails 3

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

Затем в config/environments/production.rb добавьте:

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

Обратите внимание, что предыдущая точка необходима. См. "куки файлы поддоменов, отправленные в запрос родительского домена?" для чего.

Затем в config/environments/development.rb добавьте:

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

Трюк lvh.me отображается на локальный хост. Это потрясающе. См. этот Railscast о субдоменах и это примечание для получения дополнительной информации Информация.

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

Ответ 5

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

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

Ответ 6

Вы пробовали

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

)

В основном мы говорим, что у вас есть единственный файл cookie для базового домена и просто игнорируем поддомен. Хотя этот подход еще имеет некоторые недостатки...

Ответ 7

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

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

Просто у меня есть общие файлы cookie для добавления .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