Rails 临时会话 cookie 和数据库重置

Rails temporary session cookies & db reset

我正在学习 Michael Hartl 的 Rails 教程,其中有一个部分让您在开发数据库中植入虚假用户。这个过程的第一步是运行宁rails db:migrate:reset然后你运行db:seed

当我运行这些命令时,我恰好在浏览器中登录了应用程序。 因此,我的浏览器中仍然存储了一个临时会话 cookie(通过 session[:user_id] = user.id 设置)。我的用户 ID 是 3.

因此,我发现在为数据库做种时,我可以刷新浏览器并以现在 ID 为 3 的新用户身份登录。

与此相关:注销应用程序会删除会话 cookie(通过 session.delete(:user_id))。但我发现,如果您要 (1) 在登录时复制 cookie,(2) 注销并关闭浏览器,以及 (3) 重复使用复制的 cookie(在同一个浏览器中,或另一个 machine/browser),您仍然会自动进行身份验证和登录,而无需 user/pass。是否有标准的方法来防止在注销后再次使用特定的 cookie?

这两种情况都有效,因为此 current_user 方法中的第一个条件传递并将 ID # 分配给 user_id

# Returns the current logged-in user (if any).
def current_user
  if (user_id = session[:user_id])
    @current_user ||= User.find_by(id: user_id)
  elsif (user_id = cookies.signed[:user_id])
    user = User.find_by(id: user_id)
    if user && user.authenticated?(cookies[:remember_token])
      log_in user
      @current_user = user
    end
  end
end

也许这两种情况都是非常罕见的情况。在第一种情况下,我认为重置生产应用程序的数据库是非常不可取的,记录 ID 的任何重新分配也是如此。不过,我想知道这种情况有多严重,通常会采取哪些措施来避免这种情况。非常感谢!

根据 this answer,如果您正在使用基于文件的会话,您可以使用以下方法清除所有 Rails 会话:

bundle exec rake tmp:sessions:clear

如果您正在使用数据库会话,您可以运行清除所有会话:

bundle exec rake db:sessions:clear

您还可以通过更改 config/secrets.yml 中的 secret_key_base 使会话无效。

这应该清除所有用户的所有会话。它会注销每个用户并使他们的会话无效,但这是确保在迁移数据库后旧 cookie 无法访问用户数据的最安全方法。