Skip to content

studyhaxer/day15-jwt-auth-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Day 15 — JWT Authentication API

Part of My Python Learning Streak. Day 15 extends the Day 14 User-Course API with a full JWT authentication system: registration, login, and protected routes.

Features

  • Password hashing with bcrypt via passlib — plain passwords are never stored
  • JWT-based login using python-jose — stateless auth, no server-side sessions
  • Token expiry — access tokens expire after 60 minutes
  • Protected routesget_current_user dependency guards endpoints that require a logged-in user
  • One-to-many relationship — each user can own multiple courses

Tech stack

  • FastAPI
  • SQLAlchemy (SQLite)
  • python-jose (JWT encode/decode)
  • passlib (bcrypt password hashing)

Setup

pip install fastapi uvicorn sqlalchemy python-jose[cryptography] passlib[bcrypt] python-multipart

python-multipart is required for OAuth2PasswordRequestForm to parse the login form data — easy to miss since it's not always listed alongside the other auth libraries.

Run the server:

uvicorn main:app --reload

Then open http://127.0.0.1:8000/docs for the interactive Swagger UI.

Endpoints

Method Path Auth required Description
POST /register No Register a new user (name, email, password)
POST /login No Log in with email + password, returns a JWT
GET /me Yes Return the logged-in user's profile
POST /courses Yes Create a course owned by the logged-in user
GET /users/{user_id} Yes Get a user's profile and their courses
GET /users No List all users
DELETE /users/{user_id} Yes (self only) Delete your own account

Auth flow

  1. RegisterPOST /register with name, email, password. The password is hashed with bcrypt before it touches the database.
  2. LoginPOST /login with username (your email) and password as form data. On success, you get back an access_token and token_type: bearer.
  3. Authenticated requests — send the token in the Authorization header as Bearer <token>. FastAPI's OAuth2PasswordBearer extracts it automatically.
  4. Token validationget_current_user decodes the token, reads the user ID from the sub claim, and fetches the user from the database. Missing, malformed, or expired tokens return 401 Unauthorized.

Testing in Swagger UI

  1. POST /register to create an account.
  2. POST /login and copy the access_token from the response.
  3. Click Authorize at the top of the page and paste the token.
  4. Try GET /me — you should see your own profile.
  5. Click Authorize again and log out (clear the token) — protected routes should now return 401.

Project structure

.
├── auth.py        # JWT creation/validation, password hashing, get_current_user dependency
├── database.py     # SQLAlchemy engine, session, and get_db dependency
├── main.py         # FastAPI routes
├── models.py        # User and Course ORM models
└── schemas.py        # Pydantic request/response schemas

Notes

  • SECRET_KEY in auth.py is hardcoded for learning purposes. In a real deployment, load it from an environment variable instead.
  • SQLite is used for simplicity (user_course.db). Delete this file if you change the model schema, so SQLAlchemy can recreate the tables.

Author

Ati (@studyhaxer) — Day 15 of a 60-day Python learning streak.

About

FastAPI backend with JWT authentication — user registration, login, and protected routes secured with bcrypt password hashing and python-jose tokens.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages