Правильный способ поделиться сеансами входа в систему через поддоменов в Rails 3? - PullRequest
7 голосов
/ 26 февраля 2011

Вся информация об этом, которую я нашел в интернете, говорит, что нужно использовать что-то вроде

Login::Application.config.session_store :cookie_store, :key => '_login_session', :domain => '.domain.com'

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

т.е. на login.domain.com я запускаю аутентификацию, которая возвращает имя пользователя и сессию user_id. Затем я перехожу на sub.domain.com, который должен вернуть ту же информацию, что и login.domain.com, но не возвращает. После этого я возвращаюсь на сайт login.domain.com и больше не аутентифицируюсь там.

На sub.domain.com файл session_store.rb выглядит следующим образом:

Something::Application.config.session_store :cookie_store, :key => '_login_session', :domain => '.domain.com'

Я использовал: все для значения: домен, с тем же результатом. И если я удаляю параметр: domain в приведенном выше примере, то начальный сеанс не перезаписывается, но также не становится общим.

Когда я просматриваю файлы cookie в редакторе файлов cookie для Firefox, оба субдомена используют одно и то же имя файла cookie, но аутентификация не используется совместно. Это довольно простая таблица пользователей, и я использую OpenID и OAuth для аутентификации с помощью Omniauth

Ответы [ 3 ]

6 голосов
/ 07 февраля 2013

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

tl; dr: Вам необходимо написать специальное промежуточное программное обеспечение для стойки.Вы должны добавить его в свой 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} Вы можете увидеть, что для * 1011 будут отдельные записи* и 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:Add To 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.По какой-то причине это не сработало для меня, и мне понадобился пользовательский класс 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 о поддоменах и в этой заметке для получения дополнительной информации.

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

6 голосов
/ 27 февраля 2011

обновление: предлагаемое решение не так уж и страшно, рекламные биржи и DSP / SSP используют один и тот же метод для обмена идентификатором сеанса посетителя, чтобы они могли лучше ориентировать посетителя с помощью рекламы (следующеевремя, когда посетитель снова появляется в своей сети)


Если вы можете обойти междоменный барьер браузера, вы можете это сделать.Например, JSONP специально создан для этой цели.И да, информация о сеансе всегда хранится централизованно, в противном случае, если вы получите запрос с идентификатором сеанса «зигзаг», как вы можете проверить, действителен ли он?

«Те» сайты, которые аутентифицируются на login.domain.com может использовать ajax-прокси или использовать другой метод для решения междоменной проблемы.

Самым старым «трюком» является создание в вашем приложении ловушки, которая выглядит как изображение, так как изображения могут бытьзагружен отовсюду.

Например, на login.domain.com вы аутентифицируете пользователя, отправляете его на сервер и возвращаете с ответом, и файл cookie будет храниться в login.domain.com с идентификатором сеанса (который также хранится на сервере).Затем - из Javascript - вы ПОЛУЧАЕТЕ изображение с прикрепленным идентификатором сеанса, например http://any.domain.com/path/image.jpg?sessionID=abcd -> любые файлы cookie, отправленные обратно в ответе, будут храниться в any.domain.com

Другое решение - такое же уродливое, как и предыдущее - заключается в использовании скрытого iframe для вызова any.domain.com (при успешной аутентификации), этот запрос будет возвращать ответ, ифайлы cookie будут записываться в домен any.domain.com.

Если у вас множество поддоменов и вы можете немного усложнить архитектуру, я настоятельно рекомендую вам создать прокси-сервер и сделать его доступным.на каждый поддомен на тот же IP-адрес.Тогда независимо от того, куда входит пользователь, процесс аутентификации всегда будет одинаковым для каждого субдомена.

1 голос
/ 29 марта 2011

После того, как вы настроите сеанс Rails для совместного использования между поддоменами, используя указанную выше строку, когда вы находитесь в поддомене, вы можете получить доступ к файлам cookie из домена, установив через документ JavaScript свойство document.domain для вашего домена. 1001 *

Скажем, вы находитесь в mysubdomain.domain.com, вы установите: document.domain = "domain.com"; Теперь вы сможете получить доступ к файлам cookie с домена .com.

(Обратите внимание, что вы не можете установить для document.domain какой-либо другой поддомен из-за тех же политик происхождения)

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