Add JWT Authentication to an API
A real backend problem you debug end to end in a live cloud workspace, then show on your portfolio. No tutorial, no toy app - a broken system that behaves like production.
The scenario
The API has POST /auth/login that takes a username + password and currently returns "TODO: implement JWT". Every /api/* route is wide open to the world.
The broken code you start with
@app.get("/api/users")
def list_users():
# no auth check at all - anyone can call this
return {"users": db.all_users()}What this teaches you
What you did: Wired up JWT issuance on /auth/login and added a FastAPI dependency that decodes the Authorization: Bearer <token> header on every /api/* route. PyJWT raises on bad signatures and expired tokens - you catch those and return 401.
Why it matters: JWT auth is the default for stateless APIs. The server doesn't need to store sessions - it trusts any token it signed with its own secret. Validating the signature on every request is the only thing standing between an authenticated user and an open API.
In the real world: Production JWT use needs a few more things - refresh tokens (so 1-hour expiry doesn't kick the user out), a kid header for key rotation, and asymmetric signing (RS256) if anything other than your API needs to verify tokens. The shared-secret pattern here is fine for monoliths.
What you'll practice
- Signing a JWT with HS256 and an expiry
- Verifying the Authorization Bearer token on each request
- Returning 401 on missing, malformed, or expired tokens
Why this impresses a hiring manager
- This is a real python problem teams hit in production - not a synthetic puzzle.
- It shows you can diagnose and fix a Backend issue in a live system end to end.
- It lands on your portfolio as a scenario a hiring manager can open and click through.
Implemented JWT issuance on /auth/login and a middleware that protects /api/* routes, returning 401 for missing or invalid bearer tokens
Keep going
Build this project free
You're in a real cloud workspace in 30 seconds. Fix it, and it lands on your portfolio.
Start this project →