Password hashing with bcrypt helps keep user passwords safe by turning them into secret codes that are hard to guess or steal.
When you want to store user passwords securely in a database.
When building a login system that checks passwords safely.
When you want to protect user accounts from hackers.
When you need to verify a password without saving it in plain text.
Syntax
FastAPI
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# To hash a password
hashed_password = pwd_context.hash("mysecretpassword")
# To verify a password
is_valid = pwd_context.verify("mysecretpassword", hashed_password)
Use hash() to create a hashed password from plain text.
Use verify() to check if a plain password matches the hashed one.
Examples
This creates a hashed version of "password123".
FastAPI
hashed = pwd_context.hash("password123")
This checks if "password123" matches the hashed password.
FastAPI
valid = pwd_context.verify("password123", hashed)
This will return False because the password does not match.
FastAPI
valid = pwd_context.verify("wrongpass", hashed)
Sample Program
This FastAPI app lets users register with a hashed password and login by verifying the password safely.
2. Which of the following is the correct way to import and create a bcrypt password context using passlib in FastAPI?
easy
A. from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
B. import bcrypt
pwd_context = bcrypt.PasswordContext()
C. from fastapi.security import bcrypt
pwd_context = bcrypt.Context()
D. import passlib
pwd_context = passlib.bcrypt()
Solution
Step 1: Recall correct import for bcrypt context
Passlib's CryptContext is imported from passlib.context and configured with schemes=["bcrypt"].
Step 2: Check syntax correctness
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") correctly imports and creates pwd_context with bcrypt scheme and deprecated="auto".
Final Answer:
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") -> Option A
Quick Check:
Correct import and setup = from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") [OK]
Hint: Use CryptContext from passlib.context with schemes=['bcrypt'] [OK]
Common Mistakes:
Importing bcrypt directly instead of CryptContext
Using wrong module names like fastapi.security
Calling non-existent constructors
3. Given the following code snippet, what will be the output of print(pwd_context.verify('secret123', hashed_password)) if hashed_password is generated by hashing 'secret123'?
A. Using verify method incorrectly with arguments reversed
B. No error; code works correctly
C. Not importing bcrypt module explicitly
D. Missing deprecated="auto" in CryptContext initialization
Solution
Step 1: Check CryptContext initialization
Best practice is to include deprecated="auto" to handle scheme deprecation warnings.
Step 2: Verify method usage and imports
verify is used correctly with (plain, hashed). bcrypt import is not needed explicitly with passlib.
Final Answer:
Missing deprecated="auto" in CryptContext initialization -> Option D
Quick Check:
Include deprecated="auto" to avoid warnings [OK]
Hint: Always add deprecated="auto" in CryptContext [OK]
Common Mistakes:
Omitting deprecated="auto" causes warnings
Reversing arguments in verify method
Importing bcrypt separately when unnecessary
5. You want to create a FastAPI endpoint that accepts a user's plain password, hashes it with bcrypt, and stores it securely. Which of the following code snippets correctly implements this functionality considering best practices?
hard
A. from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password)
# Store hashed_password securely
return {"msg": "User registered"}
C. from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"])
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password.encode())
return {"msg": "Password hashed"}
D. from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: bytes):
hashed_password = pwd_context.hash(password)
return {"msg": "User registered"}
Solution
Step 1: Check correct use of passlib CryptContext and hashing
from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password)
# Store hashed_password securely
return {"msg": "User registered"} correctly imports CryptContext with deprecated="auto" and hashes the plain string password.
Step 2: Validate FastAPI endpoint and parameter types
from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password)
# Store hashed_password securely
return {"msg": "User registered"} uses async def with password as str, which is standard for FastAPI input. It hashes and comments storing securely.
Step 3: Compare other options for errors
from fastapi import FastAPI
import bcrypt
app = FastAPI()
@app.post("/register")
def register(password: str):
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
return {"hashed": hashed_password} uses bcrypt module incorrectly with str instead of bytes; from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"])
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password.encode())
return {"msg": "Password hashed"} hashes password.encode() but misses deprecated="auto"; from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: bytes):
hashed_password = pwd_context.hash(password)
return {"msg": "User registered"} expects bytes input which is unusual for FastAPI JSON input.
Final Answer:
from fastapi import FastAPI
from passlib.context import CryptContext
app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@app.post("/register")
async def register(password: str):
hashed_password = pwd_context.hash(password)
# Store hashed_password securely
return {"msg": "User registered"} -> Option A
Quick Check:
Use passlib CryptContext with str input and deprecated="auto" [OK]
Hint: Use passlib CryptContext with str password and deprecated="auto" [OK]
Common Mistakes:
Using bcrypt module directly with wrong input types
Omitting deprecated="auto" in CryptContext
Accepting password as bytes instead of str in FastAPI
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.