Ruby on rails Restful身份验证:允许从多台计算机登录?

Ruby on rails Restful身份验证:允许从多台计算机登录?,ruby-on-rails,session,cookies,restful-authentication,Ruby On Rails,Session,Cookies,Restful Authentication,我们的Rails应用程序正在使用Restful身份验证进行用户/会话管理,似乎从多台计算机登录到同一帐户会终止其他计算机上的会话,从而终止“记住我”功能 假设我在家,登录应用程序(并选中“记住我”)。然后我去办公室登录(并检查“记住我”)。然后,当我回到家,我回到应用程序,必须重新登录 我如何允许从多台机器登录并使“记住我”功能在所有机器上都工作?您可以更改记住\u令牌的内容来实现这一点。您可以将其设置为: self.remember_token = encrypt("#{email}--ext

我们的Rails应用程序正在使用Restful身份验证进行用户/会话管理,似乎从多台计算机登录到同一帐户会终止其他计算机上的会话,从而终止“记住我”功能

假设我在家,登录应用程序(并选中“记住我”)。然后我去办公室登录(并检查“记住我”)。然后,当我回到家,我回到应用程序,必须重新登录


我如何允许从多台机器登录并使“记住我”功能在所有机器上都工作?

您可以更改
记住\u令牌的内容来实现这一点。您可以将其设置为:

self.remember_token = encrypt("#{email}--extrajunkcharsforencryption")
而不是

self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")

现在,令牌没有特定的计算机或时间,您可以从多台计算机保持登录状态。

这样做会牺牲一些安全性,但这绝对是可能的。有两种方法可以实现这一点

在第一种方法中,您可以覆盖用户模型中的make_令牌方法。该模型目前的实现方式如下

def make_token
  secure_digest(Time.now, (1..10).map{ rand.to_s })
end
每次用户登录时,无论是否使用cookie,都会调用
make_token
方法,该方法为用户生成并保存一个新的
memory_token
。如果您有一些用户独有的无法猜测的其他值,则可以替换
make\u token
方法

def make_token
  secure_digest(self.some_secret_constant_value)
end
这将确保令牌永远不会更改,但它还将允许获得令牌的任何人模拟用户

除此之外,如果您查看
句柄_memory_cookiemethod,您应该能够更改此方法以适合您

def handle_remember_cookie!(new_cookie_flag)
  return unless @current_<%= file_name %>
  case
  when valid_remember_cookie? then @current_<%= file_name %>.refresh_token # keeping same expiry date
  when new_cookie_flag        then @current_<%= file_name %>.remember_me 
  else                             @current_<%= file_name %>.forget_me
  end
  send_remember_cookie!
end
这三种方法都会重置令牌
forget_me
将其设置为
nil
,而另外两个将其设置为
make_token
返回的值。您可以在用户模型中重写这些方法,以防止它们在令牌存在且未过期时重置令牌。这可能是最好的方法,或者您可以向
handle\u memory\u cookie添加一些额外的逻辑方法,但这可能需要更多的工作

如果我是你,我会覆盖用户模型中的
记住我直到
忘记我
,和
刷新令牌
。以下几点应该行得通

def remember_me_until(time)
  if remember_token?
    # a token already exists and isn't expired, so don't bother resetting it
    true
  else
    self.remember_token_expires_at = time
    self.remember_token            = self.class.make_token
    save(false)
  end
end

# 
# Deletes the server-side record of the authentication token.  The
# client-side (browser cookie) and server-side (this remember_token) must
# always be deleted together.
#
def forget_me
  # another computer may be using the token, so don't throw it out
  true
end

# refresh token (keeping same expires_at) if it exists
def refresh_token
  if remember_token?
    # don't change the token, so there is nothing to save
    true     
  end
end

请注意,通过这样做,您将删除保护您免受令牌盗窃的功能。但这是一个成本效益决定。

Hmmm,您指的是什么版本的Restful身份验证?我使用的是一个非常新的版本,而且
记住\u token
设置了更复杂的方法和SHA1加密。啊,对不起。这是一个相当旧的版本,我已经运行了至少一年。没想到它变了这么多。非常感谢!那么,用户检查“记住我”的功能现在是如何工作的呢?它是否仍然按照
记住我
方法中设置的时间量记住它们?它仍然像记住我方法一样记住它们2周,但这2周从第一次使用令牌开始。换句话说,如果您从计算机A登录,然后从计算机B登录10天,4天后令牌在两台计算机上都过期。太好了。再次感谢你的帮助!
def remember_me_until(time)
  if remember_token?
    # a token already exists and isn't expired, so don't bother resetting it
    true
  else
    self.remember_token_expires_at = time
    self.remember_token            = self.class.make_token
    save(false)
  end
end

# 
# Deletes the server-side record of the authentication token.  The
# client-side (browser cookie) and server-side (this remember_token) must
# always be deleted together.
#
def forget_me
  # another computer may be using the token, so don't throw it out
  true
end

# refresh token (keeping same expires_at) if it exists
def refresh_token
  if remember_token?
    # don't change the token, so there is nothing to save
    true     
  end
end