Reference · Crypto
crypto.verify_password
crypto.verify_password(str, str | null) -> boolWhat it does
Whether a password matches a hash made by
crypto.hash_password: the password first, the
hash second. False for a wrong password, and false for anything that is not such a hash,
null included, so a user with no hash stored never gets in. It takes as long either
way (a stand-in hash is checked when there is none), so an unknown email answers no
sooner than a known one with a wrong password.
Examples
let h = crypto.hash_password("hunter2")print(crypto.verify_password("hunter2", h))print(crypto.verify_password("Hunter2", h))truefalseA sign-in page and the route its form posts to, for users stored by the sign-up on
crypto.hash_password. An unknown email makes
user null, so user.password_hash is null and the check is false: a wrong password
and an unknown email both answer 401 Wrong email or password, in the same time.
route GET /login = <form method="post" action="/login"> <input name="email" type="email" required/> <input name="password" type="password" required/> <button>Sign in</button> </form>route POST /login { form: { email: str, password: str } } { let user = db.one("select * from users where email = ?", email) if !crypto.verify_password(password, user.password_hash) { reply 401 "Wrong email or password" } set_session({ user: user.id }) redirect("/")}Edge cases
nullas the hash is false, not an error:user.password_hashof a user that was not found (null) can be given as it is.- Text that is not an Argon2id hash (an empty string, a SHA-256 from another system) is false.
- The check is exact: case and spaces in the password count.
- The hash's own salt is read from the hash, so nothing else needs storing.
print(crypto.verify_password("hunter2", null))print(crypto.verify_password("hunter2", ""), crypto.verify_password("hunter2", crypto.sha256("hunter2")))print(crypto.verify_password("hunter2 ", crypto.hash_password("hunter2")))falsefalse falsefalseErrors
A password that is not a string is a runtime error, not an error value; a hash that is anything but a string or null is treated as no hash, and gives false.
print(crypto.verify_password(null, "x"))line 1: `crypto.verify_password` expects a str as argument 1, got nullprint(crypto.verify_password("hunter2", 42))falseChaining
The password comes first, so it pipes in: password | crypto.verify_password(hash).
The result is a bool, for if or !.
let h = crypto.hash_password("hunter2")print("hunter2" | crypto.verify_password(h))print(["hunter2", "nope"] | map((p) => crypto.verify_password(p, h)))true[true, false]See also
crypto.hash_password, crypto.equal, set_session, session
Thread 0 posts
On crypto.verify_password(): questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.
Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo