Auth-System-SMTP β Summary of Important Questions & Concepts
1. Project Overview
Q: What is this project? A full-stack authentication system with email verification and password reset using SMTP. Built with FastAPI (backend) + React (frontend).
Q: What is the tech stack?
| Layer | Technology |
|---|---|
| Backend | FastAPI, SQLAlchemy, SQLite, bcrypt, JWT (python-jose) |
| Frontend | React 18, Vite, Axios, React Router v6 |
Python smtplib (STARTTLS on port 587) |
|
| Auth | Dual JWT tokens (access + refresh), bcrypt hashing, OTP verification |
2. Authentication Flow
Q: What happens during registration?
- User submits
username,email,password - Backend validates password strength (β₯8 chars, 1 letter, 1 digit)
- Password is hashed with bcrypt
- A 6-digit OTP is generated and stored in
verification_code - OTP is sent via email (SMTP or console fallback)
- User is redirected to
/verify-email
Q: How does email verification work?
- User enters email + 6-digit OTP
- Backend matches OTP against
verification_codecolumn - On success:
is_verified = True,verification_code = None - User can now log in
Q: What happens during login?
- User submits
username+password(OAuth2 form body) - Backend validates credentials with
bcrypt.checkpw() - Checks
is_activeandis_verifiedflags - Issues two JWT tokens:
- Access token: 30-minute expiry, type
"access" - Refresh token: 7-day expiry, type
"refresh"
- Access token: 30-minute expiry, type
- Frontend stores both in
sessionStorage
Q: How does token refresh work?
- Axios interceptor detects a 401 response
- Sends refresh token to
/auth/refresh - Backend validates refresh token (not revoked, valid type, user active)
- Revokes old refresh token (adds to
revoked_tokenstable) - Issues new access + refresh token pair (token rotation)
- Original request is retried with new token
Q: How does logout work?
- Frontend sends refresh token to
/auth/logout - Backend inserts both tokens into
revoked_tokenstable - Frontend clears
sessionStorageand resets user state
3. Password Reset Flow
Q: How does forgot password work?
- Step 1: User enters email β backend generates 6-digit OTP β stores in
reset_codeβ sends via email - Step 2: User enters email + code + new password β backend validates OTP β hashes new password β clears
reset_code
4. JWT Token Structure
Q: What claims are in the access token?
{
"sub": "<user_id>",
"email": "<email>",
"type": "access",
"exp": "<datetime>"
}
Q: What claims are in the refresh token?
{
"sub": "<user_id>",
"type": "refresh",
"exp": "<datetime>"
}
Q: Why use two token types?
- Access token: Short-lived, used for API requests
- Refresh token: Long-lived, used only to get new access tokens
- Separation limits exposure if a token is compromised
5. Database Schema
Q: What tables exist?
users Table
| Column | Type | Purpose |
|---|---|---|
id |
Integer (PK) | User ID |
username |
String (UNIQUE) | Login username |
email |
String (UNIQUE) | User email |
password |
String | bcrypt hashed password |
is_active |
Boolean | Account enabled/disabled |
role |
String | "user" or "admin" |
created_at |
DateTime | Registration timestamp |
is_verified |
Boolean | Email verified flag |
verification_code |
String (nullable) | Active registration OTP |
reset_code |
String (nullable) | Active password reset OTP |
revoked_tokens Table
| Column | Type | Purpose |
|---|---|---|
id |
Integer (PK) | Record ID |
token |
String (UNIQUE) | Revoked JWT string |
revoked_at |
DateTime | When it was revoked |
expires_at |
DateTime | Original token expiry |
6. API Endpoints
Q: What are all the endpoints?
Auth Routes (/auth)
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/register |
Register new user |
| POST | /auth/verify-email |
Verify email with OTP |
| POST | /auth/login |
Login, returns JWT tokens |
| POST | /auth/forgot-password |
Request password reset OTP |
| POST | /auth/reset-password |
Reset password with OTP |
| POST | /auth/refresh |
Refresh access token |
| POST | /auth/logout |
Revoke tokens |
User Routes
| Method | Endpoint | Description |
|---|---|---|
| GET | /me |
Get current user profile |
| PUT | /me |
Update profile |
| DELETE | /me |
Delete own account |
| GET | /admin/users |
List all users (admin only) |
7. Security Concepts
Q: How are passwords stored?
- Hashed with bcrypt using
bcrypt.gensalt()+bcrypt.hashpw() - Verified with
bcrypt.checkpw()(constant-time comparison)
Q: What is token revocation?
- Tokens are inserted into
revoked_tokenstable - Every authenticated request checks this table
- If token is found β 401 Unauthorized
Q: What is token rotation?
- On each refresh, the old refresh token is revoked
- A new access + refresh token pair is issued
- Prevents long-lived refresh token abuse
Q: How is rate limiting implemented?
- Custom HTTP middleware in FastAPI
- Max 60 requests per 60-second window per client IP
- Returns HTTP 429 when exceeded
Q: How is CORS configured?
- Allows only
http://localhost:5173andhttp://localhost:3000 - Allows credentials, all methods, all headers
Q: What is the SMTP fallback mechanism?
- If SMTP credentials are empty/missing β prints OTP to console
- If SMTP sending fails β falls back to console printing
- Allows development without a real mail server
8. Frontend Architecture
Q: How does the frontend manage auth state?
AuthContext(React Context) holdsuserstate- On mount, checks
sessionStorageforaccess_token - Calls
GET /meto validate and hydrate user state - If validation fails β clears session
Q: How does the axios interceptor work?
- Request interceptor: Attaches
Authorization: Bearer <token>fromsessionStorage - Response interceptor: On 401 β attempts refresh β retries request β on failure redirects to
/login
Q: What is the ProtectedRoute component?
- Wraps routes that require authentication
- Checks
userfrom AuthContext - Redirects to
/loginif not authenticated - Shows loading spinner while checking
9. Environment Variables
| Variable | Default | Purpose |
|---|---|---|
SECRET_KEY |
super_secret_dev_key_change_me_123456789 |
JWT signing key |
ALGORITHM |
HS256 |
JWT algorithm |
ACCESS_TOKEN_EXPIRE_MINUTES |
30 |
Access token TTL |
REFRESH_TOKEN_EXPIRE_DAYS |
7 |
Refresh token TTL |
DATABASE_URL |
sqlite:///./users.db |
Database connection |
SMTP_SERVER |
"" |
SMTP host (empty = simulation) |
SMTP_PORT |
587 |
SMTP port |
SMTP_USER |
"" |
SMTP login (empty = simulation) |
SMTP_PASSWORD |
"" |
SMTP password (empty = simulation) |
10. Important Security Notes & Weaknesses
Q: What security concerns exist?
.envcontains real Gmail credentials β must not be committed to version controlSECRET_KEYis a weak dev key β must be changed in production- OTP generated with
random.choices(non-cryptographic PRNG) β should usesecretsmodule forgot_passwordendpoint may expose whether an email exists (different error responses)- No per-account brute-force protection β only global rate limiter
- No
.gitignorefile β secrets could be accidentally committed
Q: What should be improved for production?
- Use a production database (PostgreSQL, MySQL) instead of SQLite
- Add
.gitignoreto exclude.env,users.db,__pycache__,node_modules - Use
secretsmodule for OTP generation - Implement account lockout after failed login attempts
- Add email rate limiting (prevent OTP spam)
- Use asymmetric JWT signing (RS256) for microservice architectures
- Add HTTPS enforcement
- Implement CSRF protection
- Add comprehensive logging and monitoring
11. Key Files Reference
| File | Purpose |
|---|---|
backend/main.py |
FastAPI app entry, CORS, rate limiting, middleware |
backend/auth.py |
Password hashing, JWT creation, SMTP email sending |
backend/models.py |
SQLAlchemy ORM models (User, RevokedToken) |
backend/schemas.py |
Pydantic request/response schemas |
backend/config.py |
Centralized config from .env |
backend/database.py |
SQLAlchemy engine, session, Base |
backend/routes/auth_routes.py |
Auth endpoints |
backend/routes/user_routes.py |
User profile + admin endpoints |
frontend/src/context/AuthContext.jsx |
Auth state management |
frontend/src/api/axios.js |
Axios instance with interceptors |
frontend/src/components/ProtectedRoute.jsx |
Route guard |
frontend/src/pages/Login.jsx |
Login form |
frontend/src/pages/Register.jsx |
Registration form |
frontend/src/pages/VerifyEmail.jsx |
OTP verification form |
frontend/src/pages/Dashboard.jsx |
User dashboard + admin panel |