В Rails, как вы уничтожаете сеанс, когда браузер закрыт? - PullRequest
4 голосов
/ 27 июля 2011

Я изучаю Railstutorial Майкла Хартла и застрял в Упражнении 9.6.2. Я искал в Интернете и использовал этот код в моем помощнике по сеансам:

module SessionsHelper

  def sign_in(user)

    session[:user_id] = user.id
    self.current_user = user
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  def signed_in?
    !current_user.nil?
  end

  def sign_out
    session[:user_id] = nil
    self.current_user = nil
  end
end

Я нашел это онлайн с: http://www.nimweb.it/web-development/ruby-on-rails-web-development/ruby-on-rails-tutorial-exercise-9-6-2-rails-session/

Однако пользователь не вышел из системы, когда браузер закрыт. У кого-нибудь еще есть решение этого?

Ответы [ 5 ]

4 голосов
/ 27 июля 2011

РЕДАКТИРОВАТЬ : Глядя на ссылку, которую вы дали, они пишут:

Мы также можем запустить сервер (с “$ rails s”) и проверить работу нашегоновый сеанс без файлов cookie (мы должны выходить из системы каждый раз, когда мы закрываем браузер).

(выделение добавлено)

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

Мой оригинальный ответ оставлен ниже для исторического значения:


(извините, если это слишком общее,Я предполагаю, что вы не видите общую картину)

По сути, в Интернете используется модель на основе запросов - клиенты отправляют запросы на выполнение каких-либо действий на сервере.

Вы не можете 'Вынудите клиента закрыть сеанс, поскольку закрытие сеанса - это действие, которое клиент должен запросить с сервера (например, путем выхода из системы).

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

Тем не менее, в JavaScript может быть какой-то способ обнаружить событие закрытия браузера и приложить максимум усилий.попытаться закрыть сеанс.Но нет никакой гарантии - пользователь всегда может принудительно завершить процесс браузера, оставив сервер в полной темноте.

Короче говоря, вы не можете рассчитывать на то, что клиент закроет сеанс.Тайм-аут, вероятно, ваш лучший вариант.

2 голосов
/ 02 марта 2012

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

1 голос
/ 19 августа 2011

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

Проверьте файл config/initializers/session_store.rb, чтобы узнать, какое хранилище сеансов используется.Предполагая, что вы ничего не изменили в хранилище, оно должно быть настроено на :cookie_store, в этом случае вам не нужно ни о чем беспокоиться, поскольку файлы cookie на стороне клиента используются для хранения данных сеанса, и эти файлы cookie по умолчанию устаревают после закрытия браузера.(это так называемые «сессионные» куки, просто для ясности, сессия здесь относится к куки, присутствующим до тех пор, пока ваш сеанс просмотра не сохранится - закрытие браузера удалит куки сессии).Конечно, это не вызывает никакого кода на стороне сервера, такого как sign_out или session.destroy при выходе из браузера, но, поскольку cookie хранит все данные сеанса и удаляется браузером, вы больше не можете получить к нему доступ, поэтому вы можете рассмотретьсеанс уничтожен ...

Теперь с хранилищем сеансов на стороне сервера это усложняется, как упоминалось в предыдущем ответе «Вы не можете« заставить »клиента закрыть сеанс» .Что большинство людей делают, так это уничтожают «истекшие» сессии вручную, например http://guides.rubyonrails.org/security.html#session-expiry. Пример задания рейка https://gist.github.com/kares/919069

0 голосов
/ 04 апреля 2016

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

Проблема не в дизайне проблемы. Конечно, ожидается, что это упражнение будет завершено с включенными файлами cookie. Скорее проблема заключается в настройке браузера: «продолжить с того места, где вы остановились» или «открыть мои окна и вкладки с прошлого раза» при запуске браузера. Этот параметр поддерживает работу сессий при закрытии браузера, и это именно то поведение, которое нам не нужно.

Эта проблема теперь упоминается как сноска в руководстве (глава 8, примечание 2). Автор говорит, что в отношении этой настройки браузера и сопутствующих ему бесконечных сеансов

... конечно, Rails не может контролировать это поведение.

0 голосов
/ 02 декабря 2011

Я читаю этот замечательный учебник прямо сейчас и получил то же задание около 30 минут назад. Джереми Роман точно ответил на вопрос в этой теме. Хотя он и не дал пошагового ответа, упомянутое им обстоятельство позволило мне найти ответ.

Теперь, чтобы быть более конкретным ... Учитывая, что Джереми упомянул о сессиях, которые автоматически истекают после закрытия браузера, если только для соответствующего куки не указан атрибут "Истекает", решение связано с на следующий кусок кода:

app/helpers/session_helper.rb:

def sign_in(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  self.current_user = user
end

Согласно самому учебнику , вышеописанный метод permanent устанавливает атрибут cookie 'Expires' равным 20.years.from_now. Таким образом, это означает, что ваш сеанс будет продолжаться в течение 20 лет, если вы явно не выйдете из системы или не удалите свой файл cookie.

Таким образом, чтобы завершить сеанс, когда браузер закрыт, вам просто нужно создать cookie без какой-либо даты истечения срока действия, которая сводится к простому пропуску permanent:

app/helpers/session_helper.rb:

def sign_in(user)
  cookies.signed[:remember_token] = [user.id, user.salt]
  self.current_user = user
end

Хотя могут быть и другие действительные решения, которые для меня еще не очевидны (в конце концов, я только начал изучать Rails), это выглядит очень простым - вам даже не нужно ничего писать - просто удалите permanent и все! :)

...