Rails 登录重置会话

Posted

技术标签:

【中文标题】Rails 登录重置会话【英文标题】:Rails Login Reset Session 【发布时间】:2011-06-16 07:35:54 【问题描述】:

当用户成功登录时调用 reset_session 并在用户注销时再次调用它是最佳做法吗?这样做有什么副作用/问题吗?

【问题讨论】:

【参考方案1】:

Ruby on Rails Security Guide 建议在身份验证成功后重置会话 ID,以防止 session fixation 漏洞。从本质上讲,会话固定涉及攻击者设置您的会话 id(或其他一些能够在您点击登录页面时知道 id 的方法),并且在您成功验证后,攻击者使用为他们自己的浏览器设置一个 cookie您的会话 ID 并随后以您的身份进行身份验证。在成功验证后重置会话 ID 可以完全缓解此类漏洞。创建操作中的一些示例代码可能如下所示:

def create
  user =  User.find_by_email(params[:email])
  if user && user.authenticate(params[:password])
    old_values = session.to_hash
    reset_session
    session.update old_values.except('session_id')
    session[:athlete_id] = athlete.id
    redirect_to root_url, notice: "Authentication successful!"
  else
    flash.now.alert = "Invalid credentials"
    render "new"
  end
end

请注意,如果您希望保留任何数据,请务必在重置之前复制会话。

就注销时调用 reset_session 而言,是的,这也是最佳实践。

【讨论】:

在 Rails 5 中,session.replace 将不再工作。但是,您可以使用 old_values = session.to_hash 获取旧值并使用 session.update(old_values) 将它们恢复到新会话。 @Ritchie 这不是复制了session_id 吗?这是故意的吗? 不,你是对的。我不确定它有什么危害。让我们把它改成old_values = session.to_hashsession.update old_values.except('session_id')【参考方案2】:

这实际上取决于您在会话中存储内容的方式以及您希望安全性如何运行。

重置会话将删除用户会话中的所有内容,因此如果他们跳回登录屏幕并重新登录,但仍然(例如)将购物车存储到他们的会话中,您将清除这可能是不受欢迎的.

如果您不存储您认为用户可能想要保留的任何数据,我知道在处理登录尝试之前清除会话完全不会有任何伤害,我建议您在注销时这样做。

【讨论】:

我大体上同意这个回复,但值得注意的是下面的@rbhitchcock 回复,特别是关于会话固定的安全指南参考。【参考方案3】:

我认为在用户登录时重置会话是一种很好的做法。这样,恶意个人无法在客户端的连接被加密之前嗅出他们的会话 cookie,并且在他们通过 https 使用登录表单后仍然使用它.试试:

temp = session
reset_session
session.reverse_merge!(temp)

这样,session 获得了由 reset_session 生成的新值,但任何其他 session 变量保持不变。

【讨论】:

这真的有效吗?在 Rails 2 中,当我尝试从会话中取出数据、调用 reset_session 并将数据重新分配回会话时,在下一次请求时它全部消失了。【参考方案4】:

由于 Rails API 发生变化,这里的很多答案都没有很好地老化,所以我只留下一个至少从 Rails 5.0 开始工作的答案。

正如其他人指出的那样,Rails 安全指南 recommends 在登录时调用 reset_session 以避免会话固定攻击。

您可能希望在登录时清除会话,但如果您只想更改会话 ID 并保留其他所有内容(即没有副作用),您可以这样做:

def mitigate_session_fixation
  old_values = session.to_hash
  reset_session
  session.update old_values.except('session_id')
end

【讨论】:

以上是关于Rails 登录重置会话的主要内容,如果未能解决你的问题,请参考以下文章

会话被 django-all auth 重置

结束会话,重置变量不起作用?

Shiro 在 2 分钟后重置会话

关于从 Rails 2 中所有浏览器中的所有活动会话自动注销的问题

在页面重新加载/刷新时重置会话?

SESSION 变量在 Codeigniter php 中的 redirect() 上被重置