是否遇到current_user所需的数据库?

时间:2015-09-30 10:44:42

标签: ruby-on-rails database authentication

我一直在关注设置简单用户身份验证的教程。以下代码用于确定用户是否已登录:

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

如果我想要做的就是确保用户已登录(并且不需要用户模型中的任何内容),我可以使用以下内容:

def is_user_logged_in
   true if session[:user_id]
end

这样,如果我想做的就是检查用户是否已登录,我就不必点击数据库。这看起来是否正确?如果是这样,有任何安全问题吗?

2 个答案:

答案 0 :(得分:1)

我不推荐这种方法。重要的是要意识到你正在做的只是检查会话变量的存在 - 这不足以确定实际用户是否已登录。你需要查询用于确定该用户是否确实存在于系统中的数据库。

此外,正如其他评论者指出的那样,通常情况下,您需要在请求的生命周期内使用当前的用户模型,因此本教程中描述的方法可以很好地为您设置。

答案 1 :(得分:1)

current_user助手由devise推广(如果您不知道的话)。

事实上,user_signed_in?方法也是popularized by devise

def user_signed_in?
    !!current_user
end

我看了一段时间的Devise;它们基本上建立在warden中间件之上。有一个很好的教程here

  

Devise宝石建立在Warden之上。守望者是一个机架   应用程序,这意味着它作为一个独立的独立运行   模块,并且(几乎总是)在主Rails之前执行   应用程序被调用。

     

Warden提供验证a身份的cookie处理   通过(安全)会话字符串登录用户,其中id(主要   特定用户的密钥)以某种方式存储和伪装。守望者也   提供一个钩子,以便您的应用程序可以处理当前不是的用户   登录。这些用户要么具有受限访问权限,要么没有访问权限   所有,当然除了登录/注册页面。

Warden非常好地处理用户身份验证。如果您需要创意,可以看看他们是如何做到的。

[warden]

-

从技术角度来看,你所做的事情绝对没有错。

然而,正如所指出的,您可能遇到的问题是系统性的;验证身份验证需要保持一致,而不仅仅是在用户设置:user_id会话后。

因此,我会做以下事情:

  1. user_id不应保存在会话变量中。至少,它应该编码与某种盐。 (人们越少了解您的用户数据结构越好)
  2. 我个人希望以某种方式验证身份验证。经过身份验证后,我会在会话中创建一个authenticated令牌,我可以将其与存储的令牌(类似于oAuth)进行比较。
  3. 关于第二个建议,你可以做一件有趣的事情。有semi-persistent storage solutions(Rails最受欢迎的是Redis),它将保存数据库身份验证,同时提供RAM类型的数据访问......

    enter image description here

    Redis基本上就像存储在内存中的数据库;你用它来存储key: value对(JSON)。更重要的是,它允许您创建一个超轻量级的身份验证系统,为您节省昂贵的SQL。

    def user_signed_in?
        return redis.get(current_user.id) ? true : false
    end
    

    虽然这是一个非常粗略的例子,但它应该让您了解缓存和外部资源如何使您能够在某种程度上简化查询。

    您可以查看用户是否在Redis中拥有正确的令牌,为您提供一组“登录”用户。没有数据库电话。