Rails教程 - 9.3.3 Current_User

时间:2011-04-07 02:12:48

标签: ruby-on-rails railstutorial.org

所以我正在关注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将如何恢复为nil。

问题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 []&amp;为什么不使用我们刚刚了解的|| =运算符?

问题3

为什么我们需要authenticate_with_salt?如果我认证&amp; sign_in可以看到id&amp;来自传递给它的用户的salt属性,为什么我们需要double_check呢?什么样的情况会引发混乱?

1 个答案:

答案 0 :(得分:4)

请记住,@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部分旨在用于执行赋值运算符。