В моем 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).





Вы почти наверняка не должны продлевать cookie сеанса, чтобы он был долговечным.
Хотя Эта статья не занимается конкретно рельсами, он довольно подробно объясняет передовой опыт «запомни меня».
Таким образом, вам следует:
Автор также рекомендует аннулировать случайное значение и сбрасывать cookie при каждом входе в систему. Лично мне это не нравится, так как тогда вы не можете оставаться на сайте на двух компьютерах. Я бы хотел убедиться, что моя функция смены пароля также сбрасывает случайное значение, блокируя сеансы на других машинах.
В заключение, совет, который он дает о том, как сделать определенные функции (смена пароля / смена электронной почты и т. д.) Недоступными для сеансов с автоматической аутентификацией, заслуживает внимания, но редко встречается в реальном мире.
Этот ответ вводит в заблуждение. Постоянные сеансы безопасны, потому что подписанные файлы cookie, предоставляемые Rails, безопасны. Есть только причина использовать метод, предложенный в этом ответе, который является «последним примечанием»: этот метод полезен, чтобы различать ручную и автоматическую (через cookie «запомнить меня») аутентификацию.
Я придумал решение, основанное на этом. Вместо того, чтобы полагаться на новый столбец, я использую Digest::SHA512.base64digest(user.password_digest) в качестве токена. password_digest уже является защищенным значением, но SHA512 защитит его еще больше. Затем я сохраняю user_id в сеансе, который находится на стороне сервера, поэтому мне нужно вычислять SHA512 только один раз за сеанс. Это будет аннулировано при изменении пароля.
Плагин restful_authentication имеет хорошую реализацию этого:
http://agilewebdevelopment.com/plugins/restful_authentication
Обратите внимание, что вы не хотите сохранять их сеанс, а только их личность. Вы создадите для них новый сеанс, когда они вернутся на ваш сайт. Обычно вы просто назначаете пользователю GUID, записываете его в их cookie, а затем используете его, чтобы найти их, когда они вернутся. Не используйте в качестве токена их имя для входа или идентификатор пользователя, поскольку его можно легко угадать и позволить хитрым посетителям захватить учетные записи других пользователей.
Я долго думал об этом и пришел к некоторым выводам. Файлы cookie сеанса Rails по умолчанию защищены от несанкционированного доступа, поэтому вам действительно не нужно беспокоиться о том, что cookie будет изменен на стороне клиента.
Вот что я сделал:
Когда пользователь устанавливает флажок «Запомнить меня», я просто устанавливаю дату сеанса [: expireson] как вход + 2 недели. Никто не может украсть cookie и оставаться в системе вечно или маскироваться под другого пользователя, потому что cookie сеанса rails защищен от несанкционированного доступа.
по умолчанию файлы cookie сеанса Rails используются только для сеанса браузера, поэтому файл cookie удаляется при закрытии браузера. Как вы выполняете первый шаг в своем решении и какую версию Rails вы используете? «Сеансовые cookie-файлы должны быть долгоживущими (около 6 месяцев)»
Я изменил настройки по умолчанию, чтобы сделать cookie сеанса не «только сеансом браузера». Этот ответ сформирован 4 года назад, и настройки / значения по умолчанию могут не применяться к более новым версиям Rails.
Я бы посоветовал вам либо взглянуть на плагин RESTful_Authentication, в котором есть его реализация, либо просто переключить вашу реализацию на использование RESTful Authentication_plugin. Есть хорошее объяснение того, как использовать этот плагин на Railscasts:
railscasts # 67 restful_authentication
Вот ссылка на сам плагин
Для меня это сработало как шарм:
http://squarewheel.wordpress.com/2007/11/03/session-cookie-expiration-time-in-rails/
Теперь мои сеансы CookieStore истекают через две недели, в результате чего пользователь должен снова отправить свои учетные данные для входа в систему в течение следующих двух недель.
По сути, это очень просто:
Я бы выбрал Devise, чтобы получить блестящее решение для аутентификации для рельсов.
Взгляните на улучшение предложенной статьи на jaspan.com/improved_persistent_login_cookie_best_practice, которая добавляет концепцию «серий» для большей безопасности. Также ваше описание неточно: 1) автор вашей статьи предлагает таблицу сопоставления один-ко-многим между пользователем и файлом cookie, чтобы избежать постоянного аннулирования вашего логина при переключении компьютеров (например, работы и дома) 2) признание недействительным случайный файл cookie не приведет к тому, что вы описываете (проблема двух компьютеров)