1

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

问题一

  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 呢?什么样的情况会引发混淆?

4

1 回答 1

4

请记住,实例变量 like@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。根据您的观点,“当前”可以表示“我当前正在查看的用户”或“我当前登录的用户”,这会导致混淆。“会话”更具体。

更新:

作为对您的附录的回应,使用cookiesto read 和to assign 的原因与 using to assign 和to read 的原因cookies.permanent大致相同。和部分旨在在练习赋值运算符时使用。flash.nowflash.permanent.now

于 2011-04-07T02:23:37.080 回答