Full-stack authentication system with email verification, two-factor login, password recovery, and JWT-based session management.
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, React 18, TypeScript, CSS Modules |
| Backend | FastAPI (Python 3.11), Uvicorn |
| Database | MongoDB (via Motor async driver) |
| Auth | JWT (python-jose), bcrypt (passlib) |
| SMTP (Gmail) | |
| Proxy | Nginx |
| Infra | Docker Compose |
make docker-upApp is available at http://localhost:3000.
Browser
|
v
Nginx (port 3000)
| |
v v
Backend (8000) Frontend (3000)
|
v
MongoDB
- Nginx reverse-proxies
/api/*to backend and/*to frontend - Frontend uses Next.js rewrites in dev mode, Nginx in production
- Backend uses a layered architecture: Routes → Services → Repositories → MongoDB
- Auth uses access tokens (15min) + refresh tokens (30d, HTTP-only cookie)
All under /api/auth except where noted.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /register |
— | Register with email + password |
| POST | /login |
— | Log in, sends verification code |
| POST | /verify-login |
— | Complete login with code |
| POST | /verify-code |
— | Verify email/registration code |
| POST | /send-verification-code |
— | Resend verification code |
| POST | /refresh |
— | Refresh access token |
| GET | /me |
Bearer | Get current user |
| POST | /logout |
Bearer | Log out |
| POST | /forgot-password |
— | Request password reset |
| POST | /reset-password |
— | Reset password with code |
| GET/PUT | /profile |
Bearer | Get/update profile |
| GET | /api/terms |
— | Terms of service |
Registration: Register → verify email via code → login
Login: Email + password → 2FA code sent via email → verify → JWT issued
Token refresh: On 401, api.ts auto-refreshes via POST /refresh; on page load, session restored from HTTP-only cookie
| Route | Page |
|---|---|
/ |
Home |
/login |
Login + 2FA |
/register |
Registration |
/verify-login |
2FA code entry |
/verify-registration |
Email verification |
/forgot-password |
Password reset |
/profile |
User profile |
/logout |
Log out |
/terms |
Terms of service |
cd backend
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000cd frontend
npm install
npm run devSet NEXT_PUBLIC_API_URL=http://localhost:8000 for API proxying.
| Variable | Default | Description |
|---|---|---|
MONGODB_URI |
mongodb://localhost:27017 |
MongoDB connection string |
MONGODB_DATABASE |
auth_system |
Database name |
SECRET_KEY |
— | JWT signing secret |
SMTP_HOST |
smtp.gmail.com |
SMTP server |
SMTP_PORT |
587 |
SMTP port |
SMTP_USERNAME |
— | SMTP login |
SMTP_PASSWORD |
— | SMTP password (app password for Gmail) |
FRONTEND_URL |
http://localhost:3000 |
Frontend URL for email links |
NEXT_PUBLIC_API_URL |
http://backend:8000 |
Backend URL for Next.js rewrites |
| Target | Description |
|---|---|
docker-up |
Build and start with Docker Compose |
docker-down |
Stop containers |
docker-logs |
Tail logs |
test |
Run all tests |
lint |
Run flake8 + ESLint |
format |
Run black |
clean |
Remove build artifacts |
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point
│ │ ├── config.py # Settings from env
│ │ ├── database.py # MongoDB connection
│ │ ├── schemas.py # Pydantic models
│ │ ├── security.py # JWT + bcrypt
│ │ ├── email_service.py # SMTP email sending
│ │ ├── dependencies.py # FastAPI DI
│ │ ├── middleware/
│ │ │ ├── csrf_middleware.py
│ │ │ └── rate_limit_middleware.py
│ │ ├── routes/ # API route handlers
│ │ ├── services/ # Business logic
│ │ ├── repositories/ # Data access layer
│ │ └── utils/ # Validators, email templates
│ ├── Dockerfile
│ └── requirements.txt
├── frontend/
│ ├── src/
│ │ ├── pages/ # Next.js pages
│ │ ├── components/ # Shared components
│ │ ├── hooks/ # useAuth, useApi
│ │ ├── context/ # AuthContext
│ │ ├── lib/ # API client, validators, constants
│ │ ├── styles/ # CSS modules
│ │ └── types/ # TypeScript types
│ ├── Dockerfile
│ └── package.json
├── infrastructure/
│ ├── docker-compose.yml
│ └── nginx.conf
├── Makefile
└── .env