0
0
FastapiHow-ToBeginner · 3 min read

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 passlib with bcrypt scheme.
  • 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.