Skip to main content

Overview

Zeus uses JWT (JSON Web Tokens) for stateless authentication. Tokens are issued after login and must be included in all API requests.

Authentication Flow

Login

POST /auth/login
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "securepassword"
}
Response:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]",
    "name": "John Doe"
  }
}

Using Tokens

Include the token in the Authorization header:
GET /wallets
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Token Validation

Server validates tokens on each request:
// Middleware validates JWT
async fn auth_middleware(
    headers: HeaderMap,
    request: Request<Body>,
    next: Next,
) -> Result<Response, AuthError> {
    let token = extract_bearer_token(&headers)?;
    let claims = validate_jwt(token)?;
    
    // Add user info to request extensions
    request.extensions_mut().insert(claims);
    
    Ok(next.run(request).await)
}

Token Expiration

Tokens expire after 24 hours. Refresh by logging in again:
POST /auth/refresh
Authorization: Bearer <expired-token>
Response:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Error Responses

Invalid Credentials

{
  "error": "Unauthorized",
  "message": "Invalid email or password"
}

Missing Token

{
  "error": "Unauthorized",
  "message": "Authorization header required"
}

Invalid Token

{
  "error": "Unauthorized",
  "message": "Invalid or expired token"
}

Implementation in Flutter

class AuthInterceptor extends Interceptor {
  final Future<String?> getToken;

  AuthInterceptor(this.getToken);

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    final token = await getToken;
    if (token != null) {
      options.headers['Authorization'] = 'Bearer $token';
    }
    handler.next(options);
  }
}

// Configure Dio
dio.interceptors.add(AuthInterceptor(() async {
  // Get token from secure storage
  return await SecureStorage.getToken();
}));

Security Best Practices

  1. Store tokens securely - Use platform secure storage
  2. Refresh before expiry - Don’t wait for 401
  3. Handle 401 gracefully - Redirect to login
  4. Use HTTPS - Never send tokens over HTTP
  5. Short expiration - Balance security vs UX