FastAPI interview question · Most asked
How do you implement OAuth2 password flow with JWT in FastAPI?
Summary
Use OAuth2PasswordBearer(tokenUrl="token") as a dependency that extracts the Bearer token, issue signed JWTs (PyJWT) at the token endpoint after verifying the password hash, and decode/verify the token in a get_current_user dependency.
Longer Answer
Hash passwords with pwdlib/passlib (Argon2 or bcrypt). The token includes sub (user ID) and exp. get_current_user decodes with a pinned algorithm, loads the user, and raises 401 with a WWW-Authenticate: Bearer header on failure. Layer authorization with dependencies like require_role('admin') or OAuth2 scopes via Security().
Code Example
import jwt
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/token")
async def login(form: Annotated[OAuth2PasswordRequestForm, Depends()], db: DbSession):
user = await authenticate(db, form.username, form.password)
if not user:
raise HTTPException(401, "Incorrect credentials", headers={"WWW-Authenticate": "Bearer"})
token = jwt.encode({"sub": str(user.id), "exp": utcnow() + timedelta(minutes=30)}, SECRET, algorithm="HS256")
return {"access_token": token, "token_type": "bearer"}
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)], db: DbSession) -> User:
try:
payload = jwt.decode(token, SECRET, algorithms=["HS256"])
except jwt.InvalidTokenError:
raise HTTPException(401, "Invalid token", headers={"WWW-Authenticate": "Bearer"})
user = await db.get(User, int(payload["sub"]))
if user is None:
raise HTTPException(401, "User not found")
return user
Key Points
OAuth2PasswordBearerextracts the token- Sign JWTs with expiry; pin algorithms
get_current_userdependency- Role/scope checks as composable dependencies
More most-asked FastAPI questions
- How does dependency injection with `Depends` work in FastAPI?
- Walk through what happens to a request in FastAPI, from the ASGI server to the response.
- What is FastAPI and what makes it different from Flask or Django?
- How do `yield` dependencies work and why are they used for database sessions?
- How does FastAPI distinguish path, query and body parameters?
- How does FastAPI use Pydantic for request validation?
- What does `response_model` (or a return annotation) do in FastAPI?
- When should an endpoint be `async def` versus plain `def` in FastAPI?