Auth-System-SMTP β High-Level Design (HLD)
1. System Overview
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT (Browser) β
β React 18 + Vite (Port 5173) β
β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββββββββββ β
β β Register β β Login β β Verify β β Dashboard β β
β β Page β β Page β β Email β β (Profile/Admin) β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββββββ¬ββββββββββ β
β β β β β β
β ββββββΌβββββββββββββββΌβββββββββββββββΌβββββββββββββββββββΌββββββββββ β
β β AuthContext (State) β β
β β + Axios Interceptors (Token) β β
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β HTTP/HTTPS
β Authorization: Bearer <token>
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API SERVER (FastAPI) β
β (Port 8000, Uvicorn) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Middleware Layer β β
β β ββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β β
β β β CORS β β Rate Limiter β β Request Logger β β β
β β β Middlewareβ β (60 req/min) β β (IP, method, path) β β β
β β ββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Route Handlers β β
β β β β
β β Auth Routes (/auth) User Routes (/me, /admin) β β
β β ββββββββββββββββββββ ββββββββββββββββββββββββ β β
β β β register β β GET /me β β β
β β β verify-email β β PUT /me β β β
β β β login β β DELETE /me β β β
β β β forgot-password β β GET /admin/users β β β
β β β reset-password β ββββββββββββββββββββββββ β β
β β β refresh β β β
β β β logout β β β
β β ββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Core Services β β
β β βββββββββββββ βββββββββββββ βββββββββββββββββββββββββ β β
β β β Auth β β Config β β Database Manager β β β
β β β Service β β Loader β β (SQLAlchemy Engine) β β β
β β β β β β β β β β
β β β bcrypt β β .env β β SQLite3 Connection β β β
β β β JWT β β variables β β Session Factory β β β
β β β SMTP Send β β β β Base (ORM) β β β
β β βββββββ¬ββββββ βββββββββββββ βββββββββββββ¬ββββββββββββ β β
β ββββββββββΌβββββββββββββββββββββββββββββββββββββΌββββββββββββββββ β
ββββββββββββββΌβββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β SMTP SERVER β β SQLite Database β
β (Gmail / Console) β β (users.db) β
β β β β
β smtp.gmail.com β β ββββββββββββββ βββββββββββββββ β
β Port 587 (STARTTLS) β β β users β βrevoked_tokensβ β
β β β ββββββββββββββ βββββββββββββββ β
β Sends OTP emails: β β β
β - Email Verify β β Tables: β
β - Password Reset β β - users β
ββββββββββββββββββββββββ β - revoked_tokens β
ββββββββββββββββββββββββββββββββββββ
2. Component Architecture
2.1 Backend Components
backend/
βββ main.py β FastAPI app, CORS, rate limiting, middleware
βββ config.py β Loads .env variables via python-dotenv
βββ database.py β SQLAlchemy engine + session + Base
βββ models.py β ORM models: User, RevokedToken
βββ schemas.py β Pydantic request/response schemas
βββ auth.py β Password hashing, JWT, SMTP email
βββ routes/
β βββ auth_routes.py β /auth endpoints (register, login, etc.)
β βββ user_routes.py β /me and /admin endpoints
βββ .env β Environment variables (secrets)
Data Flow:
Request β Middleware (CORS, Rate Limit, Logging)
β Route Handler (auth_routes / user_routes)
β Auth Service (validate token, hash password, send email)
β Database (SQLAlchemy ORM β SQLite)
β Response (JSON)
2.2 Frontend Components
frontend/
βββ src/
β βββ main.jsx β Entry point, BrowserRouter
β βββ App.jsx β Root component, all routes
β βββ index.css β Global styles (glassmorphism)
β βββ api/
β β βββ axios.js β Axios instance + interceptors
β βββ context/
β β βββ AuthContext.jsx β Auth state management
β βββ components/
β β βββ Navbar.jsx β Navigation bar
β β βββ ProtectedRoute.jsx β Route guard
β βββ pages/
β βββ Register.jsx β Registration form
β βββ Login.jsx β Login form
β βββ VerifyEmail.jsx β OTP verification form
β βββ Dashboard.jsx β User dashboard + admin panel
Component Hierarchy:
<App>
βββ <AuthProvider> (Context)
β βββ <Navbar />
β βββ <Routes>
β β βββ /register β <Register />
β β βββ /login β <Login />
β β βββ /verify-email β <VerifyEmail />
β β βββ /dashboard β <ProtectedRoute> β <Dashboard />
β β βββ / β <Navigate to="/login" />
3. Authentication Flow Diagrams
3.1 Registration Flow
ββββββββββββ ββββββββββββ ββββββββββββ
β Client β β Server β β SMTP β
ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ
β β β
β POST /auth/register β β
β { username, email, password } β β
ββββββββββββββββββββββββββββββββββββββββββΆβ β
β β β
β βββββββββββββββ€ β
β β Validate: β β
β β - Email len β β
β β - Password β β
β β strength β β
β β - Uniquenessβ β
β βββββββββββββββ€ β
β β β
β βββββββββββββββ€ β
β β bcrypt.hash β β
β β + OTP gen β β
β β + Create β β
β β User β β
β βββββββββββββββ€ β
β β β
β β Send OTP via SMTP β
β ββββββββββββββββββββββββββββββββΆβ
β β β
β 200 OK (redirect to /verify-email) β β
βββββββββββββββββββββββββββββββββββββββββββ β
β β β
β β ββββββββββββββββββββββββββ β
β β β Console fallback: β β
β β β Print OTP if SMTP failsβ β
β β ββββββββββββββββββββββββββ β
3.2 Login Flow
ββββββββββββ ββββββββββββ
β Client β β Server β
ββββββ¬ββββββ ββββββ¬ββββββ
β β
β POST /auth/login β
β (OAuth2 form: username + password) β
ββββββββββββββββββββββββββββββββββββββββββΆβ
β β
β βββββββββββββββ€
β β Look up β
β β user by β
β β username β
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β bcrypt β
β β .checkpw() β
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β Check: β
β β - is_active β
β β - is_verifiedβ
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β Generate: β
β β - access_token β
β β - refresh_token β
β βββββββββββββββ€
β β
β 200 OK β
β { access_token, refresh_token } β
βββββββββββββββββββββββββββββββββββββββββββ
β β
β Store in sessionStorage β
β Set AuthContext user β
3.3 Token Refresh Flow
ββββββββββββ ββββββββββββ
β Client β β Server β
ββββββ¬ββββββ ββββββ¬ββββββ
β β
β API Request with expired access_token β
ββββββββββββββββββββββββββββββββββββββββββΆβ
β β
β 401 Unauthorized β
βββββββββββββββββββββββββββββββββββββββββββ
β β
β Axios interceptor detects 401 β
β β
β POST /auth/refresh β
β { refresh_token } β
ββββββββββββββββββββββββββββββββββββββββββΆβ
β β
β βββββββββββββββ€
β β Decode JWT β
β β Check type β
β β == "refresh"β
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β Check if β
β β revoked β
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β Revoke old β
β β refresh tokenβ
β β (rotation) β
β βββββββββββββββ€
β β
β βββββββββββββββ€
β β Issue new β
β β access + β
β β refresh pairβ
β βββββββββββββββ€
β β
β 200 OK β
β { access_token, refresh_token } β
βββββββββββββββββββββββββββββββββββββββββββ
β β
β Retry original request with new token β
ββββββββββββββββββββββββββββββββββββββββββΆβ
β β
β 200 OK (success) β
βββββββββββββββββββββββββββββββββββββββββββ
3.4 Logout Flow
ββββββββββββ ββββββββββββ
β Client β β Server β
ββββββ¬ββββββ ββββββ¬ββββββ
β β
β POST /auth/logout β
β { refresh_token } β
β Authorization: Bearer <access_token> β
ββββββββββββββββββββββββββββββββββββββββββΆβ
β β
β βββββββββββββββ€
β β Insert both β
β β tokens into β
β β revoked_ β
β β tokens tableβ
β βββββββββββββββ€
β β
β 200 OK β
βββββββββββββββββββββββββββββββββββββββββββ
β β
β Clear sessionStorage β
β Set user = null β
β Redirect to /login β
4. Data Models
4.1 Entity Relationship Diagram
βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β users β β revoked_tokens β
βββββββββββββββββββββββββββ€ ββββββββββββββββββββββββββββββββ€
β id INTEGER PK β β id INTEGER PK β
β username VARCHAR UNI β β token VARCHAR UNI β
β email VARCHAR UNI β β revoked_at DATETIME β
β password VARCHAR β β expires_at DATETIME β
β is_active BOOLEAN β ββββββββββββββββββββββββββββββββ
β role VARCHAR β
β created_at DATETIME β Relationship: One user can have
β is_verified BOOLEAN β many revoked tokens (1:N)
β verification_code VARCHARβ
β reset_code VARCHAR β
βββββββββββββββββββββββββββ
4.2 User Model Fields
| Field | Type | Constraints | Default | Description |
|---|---|---|---|---|
id |
Integer | PK, auto-increment, indexed | β | Unique user identifier |
username |
String(50) | UNIQUE, NOT NULL, indexed | β | Login username |
email |
String(120) | UNIQUE, NOT NULL, indexed | β | User email address |
password |
String(255) | NOT NULL | β | bcrypt hashed password |
is_active |
Boolean | β | True |
Account active status |
role |
String(10) | β | "user" |
User role (user/admin) |
created_at |
DateTime | β | datetime.utcnow() |
Registration timestamp |
is_verified |
Boolean | β | False |
Email verified status |
verification_code |
String(6) | nullable | None |
Registration OTP |
reset_code |
String(6) | nullable | None |
Password reset OTP |
4.3 RevokedToken Model Fields
| Field | Type | Constraints | Default | Description |
|---|---|---|---|---|
id |
Integer | PK, auto-increment, indexed | β | Record identifier |
token |
String(512) | UNIQUE, NOT NULL, indexed | β | Full JWT string |
revoked_at |
DateTime | β | datetime.utcnow() |
Revocation timestamp |
expires_at |
DateTime | NOT NULL | β | Token original expiry |
5. Security Architecture
5.1 Authentication & Authorization Layers
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SECURITY LAYERS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Layer 1: Password Security β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β bcrypt hashing (salt + hash) β β
β β Password strength validation (β₯8 chars, 1 letter, β β
β β 1 digit) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 2: JWT Token Security β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Dual-token system (access 30min + refresh 7days) β β
β β Token rotation on refresh (old token revoked) β β
β β Token type validation (access vs refresh) β β
β β Revocation checking on every request β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 3: Email Verification β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β OTP-based email verification β β
β β 6-digit numeric code β β
β β Must verify before login β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 4: Rate Limiting β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Global: 60 requests per 60 seconds per IP β β
β β HTTP 429 when exceeded β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 5: CORS Protection β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Whitelist: localhost:5173, localhost:3000 β β
β β Credentials allowed β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 6: Role-Based Access Control β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Admin-only endpoints (/admin/users) β β
β β User role checking in route handlers β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 7: Input Validation β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Pydantic schemas for all inputs β β
β β Email validation (EmailStr) β β
β β Field length constraints β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Layer 8: Error Handling β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Generic error messages (no stack trace leak) β β
β β Request logging for audit trail β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
5.2 Token Lifecycle
ββββββββββββββββββββ
β User Login β
ββββββββββ¬ββββββββββ
β
ββββββββββΌββββββββββ
β Issue Access + β
β Refresh Tokens β
ββββββββββ¬ββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
β β β
ββββββββββΌββββββββ β ββββββββββΌββββββββ
β Use Access β β β Use Refresh β
β Token (30min) β β β Token (7days) β
ββββββββββ¬ββββββββ β ββββββββββ¬ββββββββ
β β β
ββββββββββΌββββββββ β ββββββββββΌββββββββ
β Token Expires β β β Refresh Used β
β (401 Response) β β β (Token Rotation)β
ββββββββββ¬ββββββββ β ββββββββββ¬ββββββββ
β β β
ββββββββ¬ββββββββ β
β βββββββββΌβββββββββ
ββββββββΌβββββββββ β Issue New β
β Send Refresh β β Access+Refresh β
β Token to β β Pair β
β /auth/refresh β ββββββββββββββββββ
ββββββββ¬βββββββββ
β
ββββββββΌβββββββββ
β Old Refresh β
β Token Revoked β
β (stored in DB)β
βββββββββββββββββ
6. API Design
6.1 Request/Response Schemas
Register Request:
POST /auth/register
{
"username": "string (3-50 chars)",
"email": "string (valid email)",
"password": "string (β₯8 chars, 1 letter, 1 digit)"
}
Register Response:
200 OK
{
"message": "User registered successfully. Please verify your email."
}
Login Request:
POST /auth/login
Content-Type: application/x-www-form-urlencoded
username=string&password=string
Login Response:
200 OK
{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer"
}
Refresh Request:
POST /auth/refresh
{
"refresh_token": "eyJ..."
}
Refresh Response:
200 OK
{
"access_token": "eyJ...",
"refresh_token": "eyJ..."
}
6.2 Error Response Format
401 Unauthorized
{
"detail": "Invalid authentication credentials"
}
422 Validation Error
{
"detail": [
{
"loc": ["body", "password"],
"msg": "Password must be at least 8 characters with at least one letter and one digit",
"type": "value_error"
}
]
}
429 Too Many Requests
{
"detail": "Too many requests. Please try again later."
}
7. SMTP Email System
7.1 Email Flow
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β Route β β Auth β β SMTP β
β Handler ββββββΆβ Service ββββββΆβ Server β
β β β β β β
β send_email()β β smtplib β β Gmail β
β called β β STARTTLS β β Port 587 β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β
β (if SMTP not configured or fails)
βΌ
ββββββββββββββββ
β Console β
β Fallback β
β (print OTP) β
ββββββββββββββββ
7.2 SMTP Configuration
| Setting | Value | Purpose |
|---|---|---|
| Server | smtp.gmail.com |
Gmail SMTP server |
| Port | 587 |
STARTTLS encryption |
| Protocol | STARTTLS | Upgrades plain connection to TLS |
| Auth | Username + App Password | Gmail-specific authentication |
7.3 Email Templates Sent
Email Verification:
Subject: Verify your email - Auth System
Hello {username},
Your verification code is: {otp_code}
This code will expire in 10 minutes.
If you did not register, please ignore this email.
Password Reset:
Subject: Password Reset Request - Auth System
Hello {username},
Your password reset code is: {otp_code}
This code will expire in 10 minutes.
If you did not request this, please ignore this email.
8. Frontend State Management
8.1 AuthContext Flow
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AuthContext β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β State: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β user: null | { id, username, email, role, ... } β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Methods: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β login(username, password) β β
β β β POST /auth/login β β
β β β Store tokens in sessionStorage β β
β β β Fetch user profile β β
β β β β
β β logout() β β
β β β POST /auth/logout β β
β β β Clear sessionStorage β β
β β β Set user = null β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Initialization (on mount): β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β 1. Check sessionStorage for access_token β β
β β 2. If exists β GET /me to validate β β
β β 3. If valid β set user state β β
β β 4. If invalid β clear session, set user = null β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
8.2 Axios Interceptor Chain
Request Flow:
ββββββββββββ ββββββββββββββββ ββββββββββββββββ ββββββββββββ
β API βββββΆβ Request βββββΆβ Server βββββΆβ Response β
β Call β β Interceptor β β β β β
ββββββββββββ ββββββββββββββββ ββββββββββββββββ ββββββ¬ββββββ
β β
β Attach Bearer token β
β from sessionStorage β
β
βββββββββββββββΌβββββββββββ
β Response Interceptor β
βββββββββββββββ¬βββββββββββ
β
βββββββββββββββΌβββββββββββ
β If 401: β
β 1. POST /auth/refresh β
β 2. Update tokens β
β 3. Retry request β
β 4. If fail β /login β
ββββββββββββββββββββββββββ
9. Deployment Architecture
9.1 Development Setup
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Development Environment β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Terminal 1: Backend β
β $ cd backend β
β $ source .venv/bin/activate β
β $ uvicorn main:app --reload --port 8000 β
β β
β Terminal 2: Frontend β
β $ cd frontend β
β $ npm run dev β
β β Vite dev server on http://localhost:5173 β
β β
β Database: SQLite (auto-created) β
β Email: Console fallback (no SMTP needed) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
9.2 Production Recommendations
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Production Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β Nginx βββββΆβ Uvicorn βββββΆβ PostgreSQL β β
β β (Reverse β β (Gunicorn β β (or MySQL) β β
β β Proxy) β β Workers) β β β β
β β Port 443 β β Port 8000 β β Port 5432 β β
β β HTTPS β β β β β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β β β
β β βββββββββββββββ β β
β β β Redis β β β
β β β (Cache + βββββββββββββββ€ β
β β β Rate β β β
β β β Limiting) β β β
β β βββββββββββββββ β β
β β β β
β β βββββββββββββββ β β
β βββββββββββββΆβ Static β β β
β β Files β β β
β β (React β β β
β β Build) β β β
β βββββββββββββββ β β
β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
10. Environment Configuration
| Variable | Development | Production | Purpose |
|---|---|---|---|
SECRET_KEY |
super_secret_dev_key... |
Strong random 256-bit key | JWT signing |
ALGORITHM |
HS256 |
HS256 or RS256 |
JWT algorithm |
ACCESS_TOKEN_EXPIRE_MINUTES |
30 |
15 |
Shorter in prod |
REFRESH_TOKEN_EXPIRE_DAYS |
7 |
7 |
Refresh token TTL |
DATABASE_URL |
sqlite:///./users.db |
postgresql://... |
Database |
SMTP_SERVER |
smtp.gmail.com |
smtp.gmail.com |
Email server |
SMTP_PORT |
587 |
587 |
Email port |
SMTP_USER |
user@gmail.com |
noreply@domain.com |
Email sender |
SMTP_PASSWORD |
app_password |
app_password |
Email auth |
11. Future Improvements
High Priority
- Add
.gitignore(exclude.env,users.db,__pycache__,node_modules) - Use
secretsmodule for OTP generation (cryptographic randomness) - Add per-account brute-force lockout (e.g., 5 failed attempts β 15min lock)
- Move to PostgreSQL for production use
Medium Priority
- Add Docker + docker-compose for containerized deployment
- Implement email rate limiting (prevent OTP spam)
- Add CSRF protection
- Add comprehensive unit and integration tests
- Implement account deletion with cascade (revoke all tokens)
Low Priority
- Add OAuth2 social login (Google, GitHub)
- Implement 2FA (TOTP-based)
- Add admin dashboard for user management
- Implement audit logging
- Add API versioning (v1/, v2/)