Skip to content

class Athena::PasswordHasher::Migrating
inherits Reference #

Hashes passwords with a best_hasher, while still verifying passwords hashed by any of the extra_hashers.

This allows changing the hashing algorithm of existing users without invalidating their passwords. Passwords hashed by an extra hasher need a rehash, which an APH::UserPasswordHasherInterface#needs_rehash? check can catch when the user logs in.

# Where `Argon2Hasher` is a custom `APH::Interface` implementation, e.g. using a third-party argon2 shard.
hasher = APH::Migrating.new Argon2Hasher.new, APH::Native.new

bcrypt_hash = APH::Native.new.hash "password"

hasher.verify bcrypt_hash, "password" # => true
hasher.needs_rehash? bcrypt_hash      # => true

Warning

Do not use a hasher that stores passwords in plain text as an extra hasher, otherwise a leaked hash could be used as the password itself.

Included modules

Athena::PasswordHasher::Interface

Constructors#

.new(best_hasher : APH::Interface, *extra_hashers : APH::Interface)#

View source

Methods#

#hash(plain_password : String) : String#

Returns the hash of the provided plain_password.

Raises an APH::Exception::InvalidPassword if the password is invalid, e.g. longer than MAX_PASSWORD_LENGTH.

Uses the best hasher.

View source

#needs_rehash?(hashed_password : String) : Bool#

Returns true if the provided hashed_password would benefit from being re-hashed, e.g. because it was hashed with a different algorithm or cost.

Uses the best hasher.

View source

#verify(hashed_password : String, plain_password : String) : Bool#

Returns true if the provided plain_password matches the hashed_password, otherwise false.

The extra hashers are only tried if the hashed_password needs a rehash according to the best hasher.

View source