Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python REST API — JWT Auth + SQLite + Pagination

A production-pattern FastAPI application demonstrating:

  • JWT authentication with access + refresh tokens
  • Refresh token rotation
  • Role-based access control (RBAC)
  • SQLite database with SQLAlchemy ORM
  • Reusable pagination across any endpoint
  • Comprehensive pytest test suite
  • Redis to store revoked token set

Project Structure

jwt_api/
├── main.py                  # App entry point, CORS, router registration
├── pyproject.toml           # Project metadata + dependencies
├── .env.example             # Environment variable template
├── .gitignore
│
├── core/
│   ├── config.py            # Centralised settings (env-var ready)
│   ├── security.py          # JWT create/decode, bcrypt password hashing
│   ├── dependencies.py      # get_current_user, require_admin (Depends)
│   └── pagination.py        # Reusable paginate() helper
│
├── db/
│   ├── database.py          # SQLAlchemy engine, session, get_db()
│   ├── orm_models.py        # UserORM and ProductORM table definitions
│   └── seed.py              # Seeds sample users and products on startup
│
├── models/
│   └── user.py              # Pydantic schemas for auth endpoints
│
├── routers/
│   ├── auth.py              # /register /login /refresh /logout
│   ├── users.py             # /me (any user), / and /{username} (admin only)
│   └── products.py          # Paginated products with category filter
│
└── tests/
    └── test_auth.py         # 19 tests — auth flows + pagination

Quickstart

1. Clone and install dependencies

git clone <your-repo-url>
cd jwt_api
pip install -e ".[dev]"

2. Set up environment variables

cp .env.example .env
# Edit .env and set a strong SECRET_KEY:
# openssl rand -hex 32

3. Run the server

uvicorn main:app --reload

The database is created and seeded automatically on first run.

4. Open the docs

http://127.0.0.1:8000/docs

Click Authorize → log in as alice / secret123 (admin) or bob / pass456 (user).


API Endpoints

Authentication

Method Endpoint Access Description
POST /api/v1/auth/register Public Create account
POST /api/v1/auth/login Public Get access + refresh tokens
POST /api/v1/auth/refresh Public Rotate refresh token
POST /api/v1/auth/logout Public Revoke refresh token

Users

Method Endpoint Access Description
GET /api/v1/users/me Any user Own profile
GET /api/v1/users/ Admin only Paginated user list
GET /api/v1/users/{username} Admin only Look up user

Products

Method Endpoint Access Description
GET /api/v1/products/ Any user Paginated product list
GET /api/v1/products/?category=Widgets Any user Filter by category
GET /api/v1/products/{id} Any user Single product

Pagination

All list endpoints return a consistent paginated response:

{
  "data": [...],
  "page": 1,
  "page_size": 5,
  "total": 25,
  "total_pages": 5,
  "has_next": true,
  "has_previous": false
}

Query params: ?page=1&page_size=5 (page_size max: 100)


Running Tests

pytest tests/ -v

19 tests covering:

  • Registration, login, wrong password, user enumeration prevention
  • Protected endpoints — authenticated and unauthenticated
  • RBAC — admin vs regular user
  • Refresh token rotation and reuse prevention
  • Logout and token revocation
  • Pagination — page navigation, last page, category filter, size cap

Seeded Test Accounts

Username Password Role
alice secret123 admin
bob pass456 user
carol–leo pass456 user

Security Patterns Used

Pattern Implementation
Short-lived access tokens 30 min expiry
Refresh token rotation Old token revoked on every refresh
Token type enforcement Refresh tokens rejected on protected endpoints
User enumeration prevention Same error for wrong user and wrong password
RBAC require_admin dependency chains on get_current_user
Password hashing bcrypt via direct library
Secret management Environment variables via pydantic-settings
Response stripping Pydantic response_model never leaks hashed_password

What to Add Next (Production Checklist)

  • Rate limiting — slowapi on /login and /register
  • PostgreSQL — replace SQLite for production
  • Alembic — database migrations
  • Structured logging — JSON logs per request
  • Docker + docker-compose
  • TLS termination — Nginx or AWS ALB (outside this codebase)

About

A Restful API implementation using FastAPI +JWT, Redis caching, pagination in a neatly layered single responsibility structure.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages