How to Hash Password in Flask Securely with Werkzeug
In Flask, you can hash passwords securely using
generate_password_hash from werkzeug.security. This function creates a hashed version of the password that you store instead of the plain text. To check passwords later, use check_password_hash to compare the stored hash with the entered password.Syntax
The main functions for password hashing in Flask come from werkzeug.security:
generate_password_hash(password, method='pbkdf2:sha256', salt_length=8): Creates a hashed password string from the plain password.check_password_hash(hashed_password, password): ReturnsTrueif the password matches the hashed password, otherwiseFalse.
Explanation: method defines the hashing algorithm and iterations, and salt_length adds random data to protect against rainbow table attacks.
python
from werkzeug.security import generate_password_hash, check_password_hash # Hash a password hashed = generate_password_hash('mysecretpassword') # Check a password is_correct = check_password_hash(hashed, 'mysecretpassword')
Example
This example shows how to hash a password and verify it later in a simple Flask app context.
python
from flask import Flask, request, jsonify from werkzeug.security import generate_password_hash, check_password_hash app = Flask(__name__) # Simulated user database users = {} @app.route('/register', methods=['POST']) def register(): data = request.json username = data.get('username') password = data.get('password') if username in users: return jsonify({'message': 'User already exists'}), 400 hashed_password = generate_password_hash(password) users[username] = hashed_password return jsonify({'message': 'User registered successfully'}) @app.route('/login', methods=['POST']) def login(): data = request.json username = data.get('username') password = data.get('password') hashed_password = users.get(username) if hashed_password and check_password_hash(hashed_password, password): return jsonify({'message': 'Login successful'}) return jsonify({'message': 'Invalid username or password'}), 401 if __name__ == '__main__': app.run(debug=True)
Output
Running the Flask app allows POST requests to /register and /login endpoints. Registering stores a hashed password, and login verifies it, returning success or failure messages.
Common Pitfalls
- Storing plain text passwords instead of hashed versions is insecure.
- Using weak or outdated hashing methods can be vulnerable; always use
pbkdf2:sha256or stronger. - Not verifying passwords with
check_password_hashcan cause security holes. - Rehashing an already hashed password instead of the original plain password causes login failures.
python
from werkzeug.security import generate_password_hash, check_password_hash # Wrong: hashing an already hashed password hashed_once = generate_password_hash('mypassword') hashed_twice = generate_password_hash(hashed_once) # Incorrect # Right: hash only the plain password once correct_hash = generate_password_hash('mypassword') # Checking password assert check_password_hash(correct_hash, 'mypassword') == True
Quick Reference
Remember these key points when hashing passwords in Flask:
- Use
generate_password_hashto hash plain passwords. - Use
check_password_hashto verify passwords. - Never store or log plain passwords.
- Use strong hashing methods like
pbkdf2:sha256. - Keep your dependencies updated for security fixes.
Key Takeaways
Always hash passwords with generate_password_hash before storing them.
Verify passwords using check_password_hash to ensure security.
Never store or transmit plain text passwords.
Use strong, modern hashing algorithms like pbkdf2:sha256.
Avoid hashing an already hashed password to prevent login issues.