ruby - Rails -- "remember me"能力

标签 ruby ruby-on-rails-3 remember-me

我无法理解 Michael Hartl 的 Ruby on Rails 教程中“记住我”的实现。他创建了一个带有登录方法的 SessionsHelper 模块,其中包含以下内容:

module SessionsHelper

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

    def current_user=(user)
        @current_user = user
    end

    def current_user
        return @current_user ||= user_from_remember_token
    end

    private
        def user_from_remember_token
            #passes array of length two as a parameter -- first slot contains ID,
            #second contains SALT for encryption
            User.authenticate_with_salt(*remember_token)
        end

        def remember_token
            #ensures return of a double array in the event that
            #cookies.signed[:remember_token] is nil.
            cookies.signed[:remember_token] || [nil,nil]
        end

end

注意: authenticate_with_salt User 模型中的方法通过第一个参数(id)找到用户,如果定义了用户并且其 salt 等于第二个参数(salt),则返回用户,否则返回 nil。

我无法理解为什么我们要花这么长时间来测试用户是否已经登录:

如果用户已登录,@current_user已由 sign_in 定义方法,因此 current_user 中的 ||=方法没有意义。

如果用户未登录,current_user 中的 ||= 运算符方法返回 user_from_remember_token 返回的值方法,但由于 cookies.signed[:remember_token] 将为零,User.authenticate_with_salt将传递 [nil,nil] 参数并返回 nil,因此,current_user方法将返回 nil。

简而言之,如果current_user如果方法被定义则返回@current_user,否则返回nil,使用传统的访问器方法不是更简单吗:

def current_user
    return @current_user
end

Michael Hartl 的书说这样做是没有用的,因为用户的登录状态会被遗忘。为什么会这样???有人可以解释为什么我们不这样做,而是使用上面发布的更复杂的版本吗?

最佳答案

线

return @current_user ||= user_from_remember_token

是延迟初始化的一种形式,以避免在实际需要之前初始化 @current_user 变量。 @current_user 永远不会在第一次调用此函数时初始化,但它会在每次连续调用时有一个值(假设 user_from_remember_token 返回 nil 以外的值)。

他本可以写

def current_user
  return user_from_remember_token
end

这段代码总是将当前用户初始化为它从 cookie 中读取的任何内容。这会正确运行,但他可能想避免重复读取 cookie,所以他只读取一次并将其存储在一个变量中。

他做不到

def current_user
  return @current_user
end

因为@current_user 变量不会跨页面请求持续存在。在页面呈现并发送回客户端后,@current_user 变量被销毁,它的值被遗忘。

希望这对您有所帮助。查看在 Web 应用程序中维护状态,了解有关为什么有必要跳过这些障碍的更多信息。

关于ruby - Rails -- "remember me"能力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6433908/

相关文章:

ruby-on-rails - 创建新 Rails 项目时出现 OpenSSL 错误

ruby - 在 Windows 上的 Ruby 中生成后台进程?

ruby-on-rails - 未定义的方法和错误的序列化以及 lion 上的延迟作业

Spring Security 自定义身份验证并记住我

html - 使用 ruby​​ 核心库解析 HTML? (即不需要 gem )

mysql - 用于搜索的 Rails Gem

ruby-on-rails-3 - 使用 Assets 管道 Rails 3.2 时从公用文件夹提供图像

ruby-on-rails - 使用自定义命名路由的 Rails 3 "No Route Matches"错误

php - laravel 的记住我 token 有什么用?

spring - 在 Spring 3.1 中使用记住我的功能登录用户