Password Hashing (Werkzeug)
Never store plaintext passwords.
If your database leaks and passwords are stored as plaintext, every user account is compromised.
flowchart LR
subgraph Registration
P1["password"] --> G["generate_password_hash"]
S["random salt"] --> G
G --> H["scrypt:32768:8:1$salt$digest"]
H --> DB[("password_hash column")]
end
subgraph Login
P2["attempted password"] --> C["check_password_hash"]
DB --> C
C --> R{"match?"}
R -->|yes| OK["log the user in"]
R -->|no| NO["reject -- same message as an unknown user"]
end
Hashing vs encryption
Section titled “Hashing vs encryption”- Hashing: one-way (you can’t recover original password)
- Encryption: reversible (not what you want for passwords)
Passwords should be stored as:
- salted, slow hashes
Werkzeug helpers
Section titled “Werkzeug helpers”Flask uses Werkzeug, which provides:
generate_password_hash()check_password_hash()
Example:
from werkzeug.security import generate_password_hash, check_password_hash
hashed = generate_password_hash("my_password")
assert check_password_hash(hashed, "my_password") is True
assert check_password_hash(hashed, "wrong") is FalseStore in DB
Section titled “Store in DB”Typically your user model has:
password_hashcolumn
And you never store the raw password.
Common pitfalls
Section titled “Common pitfalls”- Comparing raw passwords in code
- Using fast hashes like MD5/SHA1 for passwords (too fast)
- Logging passwords in debug logs
Werkzeug’s defaults are safe for most projects.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading