How to Hash Password in FastAPI Securely and Easily
In FastAPI, you can hash passwords securely using the
PassLib library with Bcrypt. Use CryptContext from PassLib to hash passwords before saving and verify them during login.Syntax
Use CryptContext from passlib.context to create a hashing context. Call hash() to hash a password and verify() to check a password against a hash.
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto"): sets up bcrypt hashing.pwd_context.hash(password): hashes the plain password.pwd_context.verify(plain_password, hashed_password): verifies if the plain password matches the hash.
python
from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") # Hash a password hashed_password = pwd_context.hash("mysecretpassword") # Verify password is_valid = pwd_context.verify("mysecretpassword", hashed_password)
Example
This example shows a FastAPI app with endpoints to hash a password and verify it. It demonstrates how to use CryptContext to hash passwords securely before storing or checking them.
python
from fastapi import FastAPI, HTTPException from pydantic import BaseModel from passlib.context import CryptContext app = FastAPI() pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") class User(BaseModel): username: str password: str fake_db = {} @app.post("/register") async def register(user: User): if user.username in fake_db: raise HTTPException(status_code=400, detail="User already exists") hashed_password = pwd_context.hash(user.password) fake_db[user.username] = hashed_password return {"msg": "User registered successfully"} @app.post("/login") async def login(user: User): hashed_password = fake_db.get(user.username) if not hashed_password or not pwd_context.verify(user.password, hashed_password): raise HTTPException(status_code=400, detail="Invalid username or password") return {"msg": "Login successful"}
Output
POST /register with {"username":"alice","password":"secret"} returns {"msg":"User registered successfully"}
POST /login with {"username":"alice","password":"secret"} returns {"msg":"Login successful"}
Common Pitfalls
- Never store plain passwords; always hash before saving.
- Do not use weak or outdated hashing algorithms; bcrypt is recommended.
- Always verify passwords using the same hashing context.
- Avoid re-hashing an already hashed password.
python
from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") # Wrong: Storing plain password plain_password = "mypassword" fake_db_password = plain_password # BAD # Right: Hash before storing hashed_password = pwd_context.hash(plain_password) fake_db_password = hashed_password # Wrong: Verifying with plain password string # pwd_context.verify(plain_password, plain_password) # BAD # Right: Verify with hashed password pwd_context.verify(plain_password, fake_db_password) # True
Quick Reference
Remember these key points when hashing passwords in FastAPI:
- Use
passlibwithbcryptscheme. - Hash passwords before saving to database.
- Verify passwords on login using
verify(). - Never store or log plain passwords.
Key Takeaways
Always hash passwords using PassLib's CryptContext with bcrypt before storing.
Use pwd_context.verify() to check passwords securely during login.
Never store or transmit plain text passwords to protect user data.
Avoid re-hashing hashed passwords to prevent errors.
PassLib handles salt and secure hashing automatically for you.