Реализация «Запомнить меня» в приложении Rails

В моем Rails-приложении есть поле входа с флажком «запомнить меня». Пользователи, установившие этот флажок, должны оставаться в системе даже после закрытия браузера. Я отслеживаю, вошли ли пользователи в систему, сохраняя их идентификатор в сеансе пользователя.

Но сеансы реализованы в Rails как файлы cookie сеанса, которые не являются постоянными. Могу сделать их стойкими:

class ApplicationController < ActionController::Base
  before_filter :update_session_expiration_date

  private

  def update_session_expiration_date
    options = ActionController::Base.session_options
    unless options[:session_expires]
      options[:session_expires] = 1.year.from_now
    end
  end
end

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

Редактировать

Ответ Гарета довольно хорош, но я все же хотел бы получить ответ от кого-то, кто знаком с Rails 2 (из-за его уникальности CookieSessionStore ).

Ответов (7)

Решение

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

Вот что я сделал:

  • Сессионный файл cookie настроен на долгий срок действия (около 6 месяцев)
  • Внутри хранилища сеансов
    • Дата истечения срока действия, установленная на вход + 24 часа.
    • ID пользователя
    • Authenticated = true, поэтому я могу разрешить анонимные сеансы пользователя (не опасно из-за защиты от подделки файлов cookie)
  • Я добавляю before_filter в контроллер приложений, который проверяет, истекает ли срок действия части сеанса.

Когда пользователь устанавливает флажок «Запомнить меня», я просто устанавливаю дату сеанса [: expireson] как вход + 2 недели. Никто не может украсть cookie и оставаться в системе вечно или маскироваться под другого пользователя, потому что cookie сеанса rails защищен от несанкционированного доступа.

Плагин restful_authentication имеет хорошую реализацию этого:

http://agilewebdevelopment.com/plugins/restful_authentication

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

Вы почти наверняка не должны продлевать cookie сеанса, чтобы он оставался долгоживущим.

Несмотря на то, что эта статья не касается конкретно рельсов, она довольно подробно объясняет передовой опыт «запомни меня».

Таким образом, вам следует:

  • Добавьте дополнительный столбец в пользовательскую таблицу, чтобы принять большое случайное значение
  • Установите на клиенте долгоживущий файл cookie, который сочетает в себе идентификатор пользователя и случайное значение.
  • Когда начинается новый сеанс, проверьте наличие файла cookie идентификатора / значения и аутентифицируйте нового пользователя, если они совпадают.

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

В заключение, совет, который он дает о том, как сделать определенные функции (смена пароля / смена электронной почты и т. Д.) Недоступными для сеансов с автоматической аутентификацией, заслуживает внимания, но редко встречается в реальном мире.

Я бы посоветовал вам либо взглянуть на плагин RESTful_Authentication, в котором есть его реализация, либо просто переключить вашу реализацию на использование RESTful Authentication_plugin. Есть хорошее объяснение того, как использовать этот плагин на Railscasts:

railscasts # 67 restful_authentication

Вот ссылка на сам плагин

restful_authentication

Для меня это сработало как шарм:

http://squarewheel.wordpress.com/2007/11/03/session-cookie-expiration-time-in-rails/

Теперь мои сеансы CookieStore истекают через две недели, в результате чего пользователь должен снова отправить свои учетные данные для входа в систему в течение еще двух недель.

По сути, это очень просто:

  1. включая один файл в каталог vendor / plugins
  2. установить значение истечения срока действия сеанса в контроллере приложения, используя всего одну строку

Я бы выбрал Devise, чтобы получить блестящее решение для аутентификации для рельсов.