【问题标题】:Rails Tutorial — 9.3.3 Current_UserRails 教程 — 9.3.3 Current_User
【发布时间】:2011-04-07 02:12:47
【问题描述】:

所以我正在关注Rails Tutorial,并且我已经到达了我们想要使用 sign_in SessionHelper 登录用户的部分。

问题 1

  module SessionsHelper

  def sign_in(user)
    cookies.permanent.signed[:remember_token] = [user.id, user.salt]
    current_user = user
  end

  def current_user=(user) #set current_user
    @current_user = user
  end

  def current_user #get current_user
    @current_user
  end

我遇到的困难是这样的部分:

问题是它完全无法解决我们的问题:使用该代码,用户的登录状态将被遗忘:一旦用户转到另一个页面。

我不明白这是怎么回事?我继续阅读并理解添加的代码确保@current_user 永远不会为零。但是我看不到如果我们只是在第 5 行建立 current_user 将如何恢复为零。

问题 2

更新后的代码如下:

module SessionsHelper

  def sign_in(user) #in helper because used in view & controller
    cookies.permanent.signed[:remember_token] = [user.id, user.salt]
    current_user = user
  end

  def current_user=(user) #set current_user
    @current_user = user
  end

  def current_user #get current_user
    @current_user ||= user_from_remember_token #<-- short-circuit evaluation
  end

  private

    def user_from_remember_token
      User.authenticate_with_salt(*remember_token) #*=use [] instead of 2 vars
    end

    def remember_token
      cookies.signed[:remember_token] || [nil, nil]
    end
end

在 remember_token 帮助器中,为什么它使用 cookies.signed[] 而不是 cookies.permanent.signed[] 以及为什么不使用我们刚刚了解的 ||= 运算符?

问题 3

为什么我们需要authenticate_with_salt?如果我进行身份验证和登录可以看到传递给它的用户的 id 和 salt 属性,为什么我们需要 double_check 呢?什么样的情况会引发混淆?

【问题讨论】:

  • 你真的应该把它分解成单独的问题。

标签: ruby-on-rails railstutorial.org


【解决方案1】:

请记住,@current_user 等实例变量仅在请求期间设置。控制器和视图处理程序实例是专门为只渲染一次而创建的。

通常很容易假设因为您在某处设置了一个变量,它会在未来的某个时间点继续工作,但事实并非如此。要在请求之间保留某些内容,您需要将其存储在某个地方,最方便的地方是session 设施。

此示例中缺少的内容类似于:

def current_user
  @current_user ||= User.find_by_remember_token(cookies[:remember_token])
end

通常最好使用写访问器来映射您作为示例给出的sign_in 方法的功能:

def current_user=(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  @current_user = user
end

奇怪的是,当分配当前用户的行为暗示应该是同一件事时,有一个特定的“登录”方法。

不过,从风格上看,在一个用户正在查看另一个用户的情况下,将这些方法称为 session_user 可能比 current_user 更有意义。根据您的观点,“当前”可以表示“我当前正在查看的用户”或“我当前登录的用户”,这会导致混淆。 “会话”更具体。

更新:

针对您的附录,使用cookies 读取和cookies.permanent 分配的原因与使用flash.now 分配和flash 读取的原因大致相同。 .permanent.now 部分旨在在执行赋值运算符时使用。

【讨论】:

  • 塔德曼,非常感谢。我想我理解了 95%。您提到的隐藏 session_user 的 Session 设施是什么?
  • 控制器和视图都可以使用的session 方法封装了这个功能。会话本身可以以多种方式存储,但默认是一种特殊的 cookie。其他选项包括文件系统和数据库。
  • 再次感谢您的回答。在你回答了我的前两个问题后,我添加了第三个问题。我现在意识到我应该把它分成 3 个问题。但是你有没有机会知道答案?
  • 一般三个问题应该问三个问题。 authenticate_with_salt 只是一种通过“秘密”盐解析用户的方法,我认为这是一个坏主意,因为这种信息不应该与任何人共享,即使是以加密形式。一个专用的身份验证令牌是一个更好的主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多