Mobile Authentication
Authentication flow for mobile apps and third-party integrations.
Overview
Mobile apps use a two-layer authentication system:
- App Key + Secret - Identifies your registered application
- Bearer Token - Authenticates individual users within your app
Authentication Flow
Step 1: Register Your App
Contact the Travelmode team or use the admin API to register your app and receive:
- App Key - Public identifier sent with every request
- App Secret - Private key used only for login (never expose in client code)
Step 2: User Login
Exchange user credentials + app credentials for a bearer token.
Endpoint: POST /api/auth/mobile/login
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | User's email address |
password | string | Yes | User's password |
appKey | string | Yes | Your app's public key |
appSecret | string | Yes | Your app's secret key |
deviceInfo | string | No | Device identifier for session management |
curl -X POST "https://travelmode2.replit.app/api/auth/mobile/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "userpassword",
"appKey": "tm_app_abc123...",
"appSecret": "your_app_secret...",
"deviceInfo": "iPhone 15 Pro"
}'
Response:
{
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"handle": "johndoe",
"displayName": "John Doe",
"emailVerified": true
},
"tokens": {
"accessToken": "abc123...",
"refreshToken": "xyz789...",
"accessTokenExpiresAt": "2024-01-15T13:00:00.000Z",
"refreshTokenExpiresAt": "2024-02-14T12:00:00.000Z",
"tokenType": "Bearer"
}
}
Using Bearer Tokens
After login, include the access token in all API requests:
Headers Required:
Authorization: Bearer {accessToken}X-App-Key: {appKey}
curl -X GET "https://travelmode2.replit.app/api/trips" \
-H "Authorization: Bearer abc123..." \
-H "X-App-Key: tm_app_abc123..."
Token Refresh
Access tokens expire after 1 hour. Use the refresh token to get new tokens.
Endpoint: POST /api/auth/mobile/refresh
Headers:
X-App-Key: {appKey}
Request Body:
{
"refreshToken": "xyz789..."
}
Response:
{
"tokens": {
"accessToken": "new_access_token...",
"refreshToken": "new_refresh_token...",
"accessTokenExpiresAt": "2024-01-15T14:00:00.000Z",
"refreshTokenExpiresAt": "2024-02-14T13:00:00.000Z",
"tokenType": "Bearer"
}
}
Logout
Revoke the current access token.
Endpoint: POST /api/auth/mobile/logout
Headers:
Authorization: Bearer {accessToken}X-App-Key: {appKey}
Response:
{
"success": true,
"message": "Logged out successfully"
}
Token Lifetimes
| Token Type | Lifetime | Purpose |
|---|---|---|
| Access Token | 1 hour | API request authentication |
| Refresh Token | 30 days | Obtaining new access tokens |
Security Best Practices
- Never hardcode app secrets in mobile apps - use secure storage
- Store tokens securely - Use Keychain (iOS) or Keystore (Android)
- Refresh proactively - Refresh tokens before they expire
- Handle 401 errors - Prompt re-login when tokens are invalid
- Device binding - Use deviceInfo to track and revoke specific sessions
Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Validation failed | Missing or invalid request fields |
| 401 | Invalid app credentials | App key or secret is incorrect |
| 401 | Invalid email or password | User credentials are incorrect |
| 401 | Invalid or expired refresh token | Refresh token is invalid or expired |