Authentication¶
Overview¶
The system uses a hybrid authentication model: - Access tokens: Short-lived JWT (15 minutes) - Refresh tokens: Long-lived stored tokens (7 days)
Token Flow¶
1. User logs in with email/password
2. Server validates credentials
3. Server returns: {access_token, refresh_token, expires_in}
4. Client stores tokens securely
5. Client sends requests with: Authorization: Bearer <access_token>
6. Server validates access token on each request
7. When access token expires:
- Client sends refresh_token to /auth/refresh
- Server returns new access_token
Token Structure¶
Access Token (JWT)¶
{
"sub": "user_uuid",
"tenant_id": "tenant_uuid",
"role": "courier",
"exp": 1715944800,
"iat": 1715943600
}
Refresh Token¶
Stored in database:
Password Storage¶
- Algorithm: bcrypt with salt
- Rounds: 12 (configurable)
- Never store plain passwords
Auth Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/register |
POST | Register new user |
/api/v1/auth/login |
POST | Login and get tokens |
/api/v1/auth/refresh |
POST | Refresh access token |
/api/v1/auth/logout |
POST | Revoke refresh token |
/api/v1/auth/verify-email |
POST | Verify email address |
/api/v1/auth/reset-password |
POST | Reset password flow |
Security Considerations¶
- Token Storage: Use secure storage on client (Keychain/iOS, EncryptedSharedPreferences/Android)
- Token Expiry: Short access token lifespan limits exposure if token is leaked
- Logout: Properly revoke refresh tokens on logout
- Password Reset: Expire reset codes after use or timeout
JWT Payload Hardening¶
Sensitive fields are blocked from JWT payloads to prevent token tampering:
# JWTService blocks sensitive fields
class JWTService:
SENSITIVE_FIELDS = frozenset([
"password",
"hashed_password",
"password_hash",
"secret",
"api_key",
])
def create_access_token(self, data: Dict[str, Any]) -> str:
for field in self.SENSITIVE_FIELDS:
if field in data:
raise ValueError(f"Cannot include sensitive field '{field}' in JWT payload")
This ensures that passwords, API keys, and other secrets are never accidentally included in JWT token payloads, preventing exposure through token inspection or logging.
Ver también: Authorization · OWASP · Rate Limiting