DEV Community

Fiyinfoluwa Ojo
Fiyinfoluwa Ojo

Posted on

User Model & Auth Basics: password Hashing with Bcrypt in FastAPI

Never Store Passwords in Plain Text

This is one of the most important rules in backend development.
If your database gets breached and passwords are plain text,
every user's account everywhere is compromised.

Hashing solves this; a hashed password can't be reversed.

The User Model

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, nullable=False)
    password = Column(String, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
Enter fullscreen mode Exit fullscreen mode

The Signup Endpoint

@app.post("/auth/signup", response_model=UserResponseDTO, status_code=201)
def signup(data: SignupDTO):
    # Check if email already exists
    existing = db.query(User).filter(User.email == data.email).first()
    if existing:
        raise HTTPException(status_code=400, detail="Email already registered")

    # Hash the password
    hashed_password = bcrypt.hashpw(
        data.password.encode("utf-8"),
        bcrypt.gensalt()
    )
    new_user = User(email=data.email, password=hashed_password.decode("utf-8"))
Enter fullscreen mode Exit fullscreen mode

3 things happening here:

  1. Check for duplicate emails
  2. Hash the password with bcrypt before saving
  3. Return user data without exposing the password

The Hashed Password in the DB

When you check /auth/users after signup, the password looks like:
$2b$12$eImiTXuWVxfM37uY4JANjQ...

That's bcrypt doing its job. The original password
is completely unrecoverable from this string.

Postman Tests

Successful Signup : 201

Signup success

Hashed password in DB

Hashed Password

Duplicate email : 400

Duplicate email

Lessons Learned

Bcrypt is the industry standard for password hashing.
It's slow by design, making brute force attacks
expensive. Never use MD5 or SHA1 for passwords.
Always use bcrypt, argon2, or scrypt.

Day 15 done. 15 more to go. 🔥

GDGoCBowen30dayChallenge

Top comments (0)