简体   繁体   English

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

[英]Implementation of "Remember me" in a Rails application

My Rails-app has a sign in box with a "remember me" checkbox.我的 Rails 应用程序有一个带有“记住我”复选框的登录框。 Users who check that box should remain logged in even after closing their browser.即使关闭浏览器,选中该框的用户仍应保持登录状态。 I'm keeping track of whether users are logged in by storing their id in the user's session.我通过将用户的 id 存储在用户的会话中来跟踪用户是否登录。

But sessions are implemented in Rails as session cookies, which are not persistent.但是会话在 Rails 中是作为会话 cookie 实现的,它不是持久的。 I can make them persistent:我可以他们坚持:

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

But that seems like a hack, which is surprising for such common functionality.但这似乎是一种黑客行为,对于如此常见的功能而言,这令人惊讶。 Is there any better way?有没有更好的办法?

Edit编辑

Gareth's answer is pretty good, but I would still like an answer from someone familiar with Rails 2 (because of it's unique CookieSessionStore ). Gareth 的回答非常好,但我仍然希望熟悉 Rails 2 的人的回答(因为它是独一无二的CookieSessionStore )。

You should almost certainly not be extending the session cookie to be long lived.您几乎肯定不应该将会话 cookie 扩展为长期存在。

Although not dealing specifically with rails this article goes to some length to explain 'remember me' best practices.尽管本文没有专门处理 rails, 但还是会用一定的篇幅来解释“记住我”的最佳实践。

In summary though you should:总之,你应该:

  • Add an extra column to the user table to accept a large random value向用户表添加额外的列以接受较大的随机值
  • Set a long lived cookie on the client which combines the user id and the random value在客户端上设置一个长期存在的 cookie,它结合了用户 ID 和随机值
  • When a new session starts, check for the existence of the id/value cookie and authenticate the new user if they match.当新会话开始时,检查 id/value cookie 是否存在,如果匹配则验证新用户。

The author also recommends invalidating the random value and resetting the cookie at every login.作者还建议在每次登录时使随机值无效并重置 cookie。 Personally I don't like that as you then can't stay logged into a site on two computers.就我个人而言,我不喜欢这样,因为这样您就无法在两台计算机上登录站点。 I would tend to make sure my password changing function also reset the random value thus locking out sessions on other machines.我倾向于确保我的密码更改功能也重置随机值,从而锁定其他机器上的会话。

As a final note, the advice he gives on making certain functions (password change/email change etc) unavailable to auto authenticated sessions is well worth following but rarely seen in the real world.最后,他给出的关于使某些功能(密码更改/电子邮件更改等)对自动验证会话不可用的建议非常值得遵循,但在现实世界中很少见。

I have spent a while thinking about this and came to some conclusions.我花了一段时间思考这个问题并得出了一些结论。 Rails session cookies are tamper-proof by default, so you really don't have to worry about a cookie being modified on the client end.默认情况下,Rails 会话 cookie 是防篡改的,因此您真的不必担心 cookie 在客户端被修改。

Here is what I've done:这是我所做的:

  • Session cookie is set to be long-lived (6 months or so)会话 cookie 设置为长期存在(6 个月左右)
  • Inside the session store会话存储内部
    • An 'expires on' date that is set to login + 24 hours设置为登录 + 24 小时的“过期”日期
    • user id用户身份
    • Authenticated = true so I can allow for anonymous user sesssions (not dangerous because of the cookie tamper protection) Authenticated = true 这样我就可以允许匿名用户会话(由于 cookie 篡改保护,所以不危险)
  • I add a before_filter in the Application Controller that checks the 'expires on' part of the session.我在应用程序控制器中添加了一个 before_filter 来检查会话的“过期”部分。

When the user checks the "Remember Me" box, I just set the session[:expireson] date to be login + 2 weeks.当用户选中“记住我”框时,我只是将会话 [:expireson] 日期设置为登录 + 2 周。 No one can steal the cookie and stay logged in forever or masquerade as another user because the rails session cookie is tamper-proof.没有人可以窃取 cookie 并永远保持登录状态或伪装成另一个用户,因为 rails 会话 cookie 是防篡改的。

I would suggest that you either take a look at the RESTful_Authentication plug in, which has an implementation of this, or just switch your implementation to use the RESTful Authentication_plugin.我建议您查看 RESTful_Authentication 插件,它有一个实现,或者只是将您的实现切换为使用 RESTful Authentication_plugin。 There is a good explanation about how to use this plug in at Railscasts:关于如何在 Railscasts 中使用这个插件有一个很好的解释:

railscasts #67 restful_authentication railscasts #67 restful_authentication

Here is a link to the plugin itself这是插件本身的链接

restful_authentication restful_authentication

The restful_authentication plugin has a good implementation of this: restful_authentication 插件有一个很好的实现:

http://agilewebdevelopment.com/plugins/restful_authentication http://agilewebdevelopment.com/plugins/restful_authentication

Note that you don't want to persist their session, just their identity.请注意,您不想保留他们的会话,只想保留他们的身份。 You'll create a fresh session for them when they return to your site.当他们返回到您的网站时,您将为他们创建一个新的会话。 Generally you just assign a GUID to the user, write that to their cookie, then use it to look them up when they come back.通常,您只需为用户分配一个 GUID,将其写入他们的 cookie,然后在他们回来时使用它来查找他们。 Don't use their login name or user ID for the token as it could easily be guessed and allow crafty visitors to hijack other users' accounts.不要使用他们的登录名或用户 ID 作为令牌,因为它很容易被猜到,并允许狡猾的访问者劫持其他用户的帐户。

This is a pretty good write-up of one guys experience of creating 30-day persistent sessions. 这是一个很好的写一个人创建30天持久会话的经验。

WARNING: blog post is from 2006 警告:博客文章是从2006年开始的

http://grahamglass.blogs.com/main/2006/05/rails_sessionsr.html http://grahamglass.blogs.com/main/2006/05/rails_sessionsr.html

This worked like a charm for me:这对我来说就像一个魅力:

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

Now my CookieStore sessions expire after two weeks, whereby the user must submit their login credentials again in order to be persistently logged-in for another two weeks.现在,我的 CookieStore 会话将在两周后到期,因此用户必须再次提交其登录凭据才能再持续登录两周。

Bascially, it's as simple as:基本上,它很简单:

  1. including one file in vendor/plugins directory在 vendor/plugins 目录中包含一个文件
  2. set session expiry value in application controller using just one line仅使用一行在应用程序控制器中设置会话到期值

我会选择 Devise 为 Rails 提供出色的身份验证解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM