Реализация «Запомнить меня» в приложении 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).

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
54
0
11 290
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

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

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

Взгляните на улучшение предложенной статьи на jaspan.com/improved_persistent_login_cookie_best_practice, которая добавляет концепцию «серий» для большей безопасности. Также ваше описание неточно: 1) автор вашей статьи предлагает таблицу сопоставления один-ко-многим между пользователем и файлом cookie, чтобы избежать постоянного аннулирования вашего логина при переключении компьютеров (например, работы и дома) 2) признание недействительным случайный файл cookie не приведет к тому, что вы описываете (проблема двух компьютеров)

cherouvim 14.04.2010 17:09

Этот ответ вводит в заблуждение. Постоянные сеансы безопасны, потому что подписанные файлы cookie, предоставляемые Rails, безопасны. Есть только причина использовать метод, предложенный в этом ответе, который является «последним примечанием»: этот метод полезен, чтобы различать ручную и автоматическую (через cookie «запомнить меня») аутентификацию.

collimarco 22.07.2013 15:35

Я придумал решение, основанное на этом. Вместо того, чтобы полагаться на новый столбец, я использую Digest::SHA512.base64digest(user.password_digest) в качестве токена. password_digest уже является защищенным значением, но SHA512 защитит его еще больше. Затем я сохраняю user_id в сеансе, который находится на стороне сервера, поэтому мне нужно вычислять SHA512 только один раз за сеанс. Это будет аннулировано при изменении пароля.

bradlis7 08.02.2017 21:31

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

http://agilewebdevelopment.com/plugins/restful_authentication

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

Ответ принят как подходящий

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

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

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

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

по умолчанию файлы cookie сеанса Rails используются только для сеанса браузера, поэтому файл cookie удаляется при закрытии браузера. Как вы выполняете первый шаг в своем решении и какую версию Rails вы используете? «Сеансовые cookie-файлы должны быть долгоживущими (около 6 месяцев)»

Nick B 08.02.2012 06:08

Я изменил настройки по умолчанию, чтобы сделать cookie сеанса не «только сеансом браузера». Этот ответ сформирован 4 года назад, и настройки / значения по умолчанию могут не применяться к более новым версиям Rails.

Daniel Beardsley 01.03.2012 06:12

Я бы посоветовал вам либо взглянуть на плагин 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, чтобы получить блестящее решение для аутентификации для рельсов.

Другие вопросы по теме