【问题标题】:Rails has_secure_password: is it actually hashing the password in the DB?Rails has_secure_password:它实际上是在数据库中散列密码吗?
【发布时间】:2014-04-21 20:29:34
【问题描述】:

使用带有has_secure_password 的典型Rails 4.1 应用程序,User 模型在数据库中有一个password_digest 列。当我创建新用户时,我仍然可以在控制台中访问明文密码:

# in rails console
> u = User.new(email: "test@test.com", password: "password")
> u.save
> u.password => "password"
> u.password_digest => "xjdk..."

但是,当我关闭控制台会话并开始新的会话时,我无法再检索明文密码:

# close above console session and open a new one
> u = User.find_by(email: "test@test.com")
> u.password => nil

我假设明文密码只能在第一种情况下检索,因为它存储在内存中,当我调用 u.password => "password" 时,它是从内存中检索值,而不是从数据库中检索。

我一直认为has_secure_password 将(盐+密码)存储为哈希,我认为这意味着理论上不可能(如果我可以使用该术语)反转password_digest 并获得原始密码。

我只是确保密码存储为真实哈希(即无法检索原始密码)的假设是有效的。我已经阅读了Rails has_secure_password API,但它并没有澄清我的问题。

【问题讨论】:

    标签: security bcrypt password-hash ruby-on-rails-4.1


    【解决方案1】:

    你是对的——数据库只保存散列密码,而不是密码本身。您可以通过使用read_attribute 方法(http://www.rubydoc.info/docs/rails/3.0.0/ActiveRecord/AttributeMethods/Read)直接访问数据库来确认这一点:

    > u = User.new …
    > u.read_attribute(:password_digest)
    => # Some hash
    > u.read_attribute(:password)
    => nil
    

    顺便说一句,还要确保您的User 模型没有password 列。否则它将直接保存password,从而破坏了对密码进行哈希处理的目的。

    【讨论】:

    • 澄清一下,password 属性是一个instance attribute。只要用户对象在内存中,它就会一直存在。当您随后加载相同的用户对象时,password 属性将为 nil。
    猜你喜欢
    • 2015-10-26
    • 2019-12-27
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    相关资源
    最近更新 更多