在Rails应用程序中实现"记住我"

Michiel de Mare 49 ruby ruby-on-rails http

我的Rails-app有一个带有"记住我"复选框的登录框.检查该框的用户即使在关闭浏览器后仍应保持登录状态.我通过在用户的会话中存储他们的id来跟踪用户是否登录.

但会话在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

但这似乎是一种黑客攻击,这对于这种常见功能而言是令人惊讶的.有没有更好的方法?

编辑

Gareth的答案非常好,但我仍然希望得到Rails 2熟悉的人的回答(因为它是独一无二的CookieSessionStore).

Gareth Simps.. 27

您几乎肯定不会将会话cookie扩展为长期存在.

虽然没有专门讨论rails,但本文还是花了一些篇幅来解释"记住我"的最佳实践.

总之,你应该:

  • 在用户表中添加一个额外的列以接受大的随机值
  • 在客户端上设置一个长期存在的cookie,它结合了用户ID和随机值
  • 当新会话开始时,检查是否存在id/value cookie,并在新用户匹配时对其进行身份验证.

作者还建议使随机值无效并在每次登录时重置cookie.我个人不喜欢那样,因为你不能保持登录两台计算机上的网站.我倾向于确保我的密码更改功能也重置随机值,从而锁定其他机器上的会话.

作为最后一点,他提供的关于使某些功能(密码更改/电子邮件更改等)对自动认证会话不可用的建议非常值得关注,但在现实世界中很少见到.

  • 请查看http://jaspan.com/improved_persistent_login_cookie_best_practice上建议文章的改进,其中添加了"系列"概念以提高安全性.此外,您的描述不准确:1)您的文章的作者建议用户和cookie之间的一对多映射表,以避免在切换计算机(即工作和家庭)时不断使您的登录失效2)无效随机cookie不会导致你描述的内容(两台电脑有问题) (3认同)

Daniel Beard.. 10

我花了一些时间思考这个并得出了一些结论.Rails会话cookie默认是防篡改的,所以你真的不必担心在客户端修改cookie.

这就是我所做的:

  • 会话cookie设置为长期(大约6个月)
  • 在会话商店内
    • 设置为登录+ 24小时的'到期'日期
    • 用户身份
    • Authenticated = true所以我可以允许匿名用户sesssions(因为cookie篡改保护而没有危险)
  • 我在Application Controller中添加了一个before_filter,用于检查会话的"expires on"部分.

当用户选中"记住我"框时,我只将会话[:expireson]日期设置为登录+ 2周.没有人可以窃取cookie并永远登录或伪装成另一个用户,因为rails会话cookie是防篡改的.


Mattew.. 9

我建议你看一下RESTful_Authentication插件,它有一个实现,或者只是切换你的实现来使用RESTful Authentication_plugin.关于如何在Railscasts中使用此插件有一个很好的解释:

railscasts#67 restful_authentication

这是插件本身的链接

restful_authentication


Jarin Udom.. 5

restful_authentication插件有一个很好的实现:

http://agilewebdevelopment.com/plugins/restful_authentication