Using typical Rails 4.1 app with has_secure_password
and the User
model has a password_digest
column in the DB. When I create a new user, I can still access the plaintext password in the console:
# in rails console
> u = User.new(email: "test@test.com", password: "password")
> u.save
> u.password => "password"
> u.password_digest => "xjdk..."
However, when I close the console session and start a new one, I can no longer retrieve the plaintext password:
# close above console session and open a new one
> u = User.find_by(email: "test@test.com")
> u.password => nil
I'm assuming that the plaintext password is only retrievable in the first situation because it's being stored in memory and when I call u.password => "password"
it is retrieving the value from memory, NOT the database.
I had always thought has_secure_password
stored the (salt + password) as a hash and I thought that meant it was theoretically impossible (if I can use that terminology) to reverse the password_digest
and get the original password.
I'm just making sure my assumption that the password is stored as a real hash (ie, can't retrieve original password) is valid. I've read the Rails has_secure_password API but it didn't clarify my question.
You are correct — the DB is only saving the hashed password, not the password itself. You can confirm this by accessing the database directly using the read_attribute
method (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
Incidentally, also make sure your User
model does not have a password
column. Otherwise it would save the password
directly, defeating the purpose of hashing the password.