api-v1/AUTH_FLOW.md

189 lines
4.8 KiB
Markdown

# Authentication Flow - BuySellService → Auth Service
## Overview
BuySellService **does NOT validate JWT tokens locally**. Instead, it calls the auth service API to validate and authorize every request.
## Flow Diagram
```
Android App → BuySellService → Auth Service → BuySellService → Response
| | | |
| | | |
[Token] [Extract Token] [Validate Token] [User Info]
| | | |
| | | |
└──────────────┴────────────────┴───────────────┘
```
## Detailed Flow
### 1. Request Arrives at BuySellService
**Android App sends:**
```
GET http://localhost:3200/users/user-123
Authorization: Bearer eyJhbGc...
```
### 2. BuySellService Middleware Chain
**Step 1: requestContext**
- Extracts IP, User-Agent, generates Request-ID
**Step 2: auditLogger**
- Attaches audit logger to request
**Step 3: jwtAuthenticate****CALLS AUTH SERVICE**
- Extracts token from `Authorization: Bearer <token>` header
- **Calls auth service**: `POST http://localhost:3000/auth/validate-token`
- **Request body**: `{ token: "eyJhbGc..." }`
- **Waits for response**
### 3. Auth Service Validates Token
**Auth Service receives:**
```json
POST /auth/validate-token
Body: { "token": "eyJhbGc..." }
```
**Auth Service validates:**
- ✅ Token signature (using JWT secret)
- ✅ Token expiry (`exp` claim)
- ✅ Issuer (`iss` claim)
- ✅ Audience (`aud` claim)
- ✅ Token version (checks database for logout-all-devices)
- ✅ User exists in database
**Auth Service responds (if valid):**
```json
{
"valid": true,
"payload": {
"sub": "user-123",
"role": "user",
"user_type": "seller",
"phone_number": "+919876543210",
"token_version": 1,
"high_assurance": false
}
}
```
**Auth Service responds (if invalid):**
```json
{
"valid": false,
"error": "Invalid or expired token"
}
```
### 4. BuySellService Receives Response
**If valid:**
- Extracts user info from `payload`
- Sets `req.user = { userId: "user-123", role: "user", ... }`
- Logs successful authentication
- Continues to next middleware
**If invalid:**
- Returns `401 Unauthorized`
- Logs failed authentication
- Stops request processing
### 5. Continue with Authorization
**After authentication:**
- Rate limiting (checks limits for userId)
- Coarse-grained authorization (checks role)
- Fine-grained authorization (checks resource ownership)
- Route handler (fetches user data)
- Response returned to Android app
## Code Flow
```javascript
// Backend/middleware/jwtAuthenticate.js
async function jwtAuthenticate(req, res, next) {
// 1. Extract token
const token = req.headers.authorization?.slice(7); // "Bearer <token>"
// 2. Call auth service
const response = await axios.post(
'http://localhost:3000/auth/validate-token',
{ token }
);
// 3. Check response
if (response.data.valid === true) {
// 4. Extract user info
req.user = {
userId: response.data.payload.sub,
role: response.data.payload.role,
// ... other fields
};
next(); // Continue to next middleware
} else {
// 5. Return 401 if invalid
return res.status(401).json({ error: 'Unauthorized' });
}
}
```
## Benefits
**Centralized Validation**: All token validation logic in one place (auth service)
**No Secret Sharing**: BuySellService doesn't need JWT secret
**Token Version Checking**: Auth service checks database for logout-all-devices
**Consistent**: All services use same validation logic
**Easy Updates**: Update validation logic once in auth service
## Error Handling
**Auth Service Unavailable:**
- Returns `401 Unauthorized` with message: "Authentication service unavailable"
- Request is blocked (fail closed for security)
**Token Invalid:**
- Returns `401 Unauthorized` with error details
- Request is blocked
**Timeout:**
- 5 second timeout by default (configurable via `AUTH_SERVICE_TIMEOUT`)
- Returns `401 Unauthorized` if timeout exceeded
## Configuration
**Required Environment Variables:**
```env
AUTH_SERVICE_URL=http://localhost:3000
```
**Optional:**
```env
AUTH_SERVICE_TIMEOUT=5000 # milliseconds
```
## Testing
**Test auth service endpoint directly:**
```bash
# Valid token
curl -X POST http://localhost:3000/auth/validate-token \
-H "Content-Type: application/json" \
-d '{"token":"your_valid_token_here"}'
# Response:
# {"valid":true,"payload":{"sub":"user-123","role":"user",...}}
```
**Test through BuySellService:**
```bash
curl -X GET http://localhost:3200/users/user-123 \
-H "Authorization: Bearer your_valid_token_here"
```
The BuySellService will call the auth service internally to validate the token.