Files
memory-infrastructure-palace/docs/projects/Pokedex.Online/architecture/authentication.md

323 lines
9.1 KiB
Markdown

# JWT Authentication Architecture
**Last Updated:** January 28, 2026
**Status:** ✅ Implemented (Step 9 Complete)
## Overview
Pokedex.Online uses JWT (JSON Web Token) authentication for admin access to protected features like the Gamemaster Manager. The system provides:
- Token-based authentication (stateless)
- 7-day token expiration with refresh capability
- Permission-based access control
- Secure localStorage token storage
- Automatic Bearer token injection in API requests
## Architecture Diagram
```
┌─────────────────────────────────────────────────────────────┐
│ Client (Browser) │
├─────────────────────────────────────────────────────────────┤
│ │
│ AdminLogin View │
│ ↓ (password) │
│ useAuth Composable (login → POST /auth/login) │
│ ↓ (token received) │
│ localStorage.setItem('auth_token', token) │
│ ↓ │
│ api-client.setDefaultHeader('Authorization', Bearer ...) │
│ ↓ │
│ Router Guards (requiresAdmin check) │
│ ↓ │
│ Protected Routes (GamemasterManager, etc.) │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Server (Express) │
├─────────────────────────────────────────────────────────────┤
│ │
│ Auth Routes (server/routes/auth.js) │
│ ↓ /auth/login (POST) → verifyPassword │
│ ↓ createToken(payload, secret, expiration) │
│ ↓ return { token, user, expiresIn } │
│ │
│ Auth Middleware (server/middleware/auth.js) │
│ ↓ authMiddleware() → verifyToken(token) │
│ ↓ requirePermission() → check permissions │
│ ↓ requireAdmin() → check isAdmin flag │
│ │
│ Protected Routes │
│ ↓ /api/gamemaster/* (with @authMiddleware) │
│ ↓ /api/feature-flags/* (with @requirePermission) │
│ │
└─────────────────────────────────────────────────────────────┘
```
## File Structure
```
Frontend:
├── src/
│ ├── composables/
│ │ └── useAuth.js # Auth state management
│ ├── views/
│ │ └── AdminLogin.vue # Login page
│ ├── router/
│ │ └── guards.js # Route protection
│ └── utilities/
│ └── api-client.js # Enhanced with header mgmt
Backend:
├── server/
│ ├── utils/
│ │ └── jwt-utils.js # Token creation/validation
│ ├── middleware/
│ │ └── auth.js # Auth middleware
│ └── routes/
│ └── auth.js # Auth endpoints
Tests:
└── tests/unit/
├── composables/
│ └── useAuth.test.js # Auth composable tests
└── views/
└── AdminLogin.test.js # Login page tests
```
## API Endpoints
### POST /auth/login
Authenticate with password to receive JWT token.
**Request:**
```json
{
"password": "admin-password"
}
```
**Response (Success):**
```json
{
"success": true,
"token": "eyJhbGc...",
"expiresIn": 604800,
"user": {
"isAdmin": true,
"permissions": ["admin", "gamemaster-edit"]
}
}
```
**Response (Error):**
```json
{
"error": "Invalid password",
"code": "INVALID_PASSWORD"
}
```
### POST /auth/verify
Verify that a token is valid and get its metadata.
**Request:**
```json
{
"token": "eyJhbGc..."
}
```
**Response:**
```json
{
"valid": true,
"user": {
"isAdmin": true,
"permissions": ["admin", "gamemaster-edit"]
},
"expiresIn": 3600,
"expiresAt": "2026-02-04T17:48:00Z"
}
```
### POST /auth/refresh
Extend token expiration.
**Request:**
```json
{
"token": "eyJhbGc..."
}
```
**Response:**
```json
{
"success": true,
"token": "eyJhbGc...",
"expiresIn": 604800
}
```
### GET /auth/user
Get current user information (requires valid token).
**Headers:**
```
Authorization: Bearer eyJhbGc...
```
**Response:**
```json
{
"user": {
"isAdmin": true,
"permissions": ["admin", "gamemaster-edit"],
"loginTime": "2026-01-28T17:48:00Z"
}
}
```
### POST /auth/logout
Logout endpoint (token invalidation happens client-side).
**Response:**
```json
{
"success": true,
"message": "Logged out successfully"
}
```
## Frontend Integration
### Using useAuth in Components
```javascript
import { useAuth } from '../composables/useAuth.js';
export default {
setup() {
const {
login, // login(password)
logout, // logout()
token, // Reactive token ref
user, // Reactive user ref
isAuthenticated, // Boolean computed
isAdmin, // Boolean computed
hasPermission // (perm) => boolean
} = useAuth();
return {
login,
logout,
token,
user,
isAuthenticated,
isAdmin,
hasPermission
};
}
};
```
### Protected Routes
```javascript
import { setupAuthGuards } from './router/guards.js';
const router = createRouter({ ... });
setupAuthGuards(router);
// In route definitions:
{
path: '/gamemaster-manager',
component: GamemasterManager,
meta: { requiresAdmin: true } // Protected route
}
```
### Setting Up Auth on App Startup
```javascript
import { useAuth } from './composables/useAuth.js';
export default {
async setup() {
const { initializeAuth, setupAuthInterceptor } = useAuth();
// Initialize from localStorage
await initializeAuth();
// Set up automatic token injection
setupAuthInterceptor();
}
};
```
## Security Considerations
### ✅ Implemented
- JWT tokens with HMAC-SHA256 signature
- 7-day expiration with refresh capability
- Bearer token in Authorization header
- Token stored in localStorage (browser-side)
- Permission-based access control
- Server-side token validation
### ⚠️ Recommendations
For production deployment:
1. **HTTPS Only:** Ensure all authentication over HTTPS
2. **Environment Secrets:** Store JWT_SECRET in environment variables
3. **Password Hashing:** Use bcrypt for password hashing on server
4. **CSRF Protection:** Add CSRF tokens for state-changing requests
5. **Rate Limiting:** Implement rate limiting on /auth/login endpoint
6. **Secure Cookies:** Consider httpOnly cookies for sensitive tokens
7. **Token Rotation:** Implement token rotation for long-lived sessions
8. **Logout Blacklist:** Maintain blacklist of revoked tokens (if needed)
### Current Limitations
- Passwords stored in environment/config (suitable for single admin scenario)
- No multi-user support yet (planned for future)
- Tokens valid until expiration (no immediate revocation)
- Single secret key (key rotation not yet implemented)
## Testing
Tests verify:
✅ useAuth composable state management
✅ AdminLogin component rendering and interaction
✅ Login/logout flow
✅ Token state in localStorage
✅ Permission checking logic
✅ Router guard integration
Run tests:
```bash
npm test # Watch mode
npm test -- AdminLogin # Specific test
npm run test:coverage # Coverage report
```
## Next Steps (Phase 3: Steps 10-12)
- Feature flags system leveraging JWT permissions
- Secure backend configuration management
- Environment-based flag toggleput
- Flag caching and invalidation
- Admin panel for flag management
---
**Related Documentation:**
- [PROGRESS.md](./PROGRESS.md) - Full refactoring progress
- [REFACTORING-PLAN.md](./REFACTORING-PLAN.md) - Complete 68-step plan