12 KiB
12 KiB
Authentication & Login
This document describes the authentication flow, login process, and session management.
Overview
The app supports two authentication methods:
- Email/Password Login - Traditional credentials
- OAuth Login - External identity provider (SSO)
Login Flow Diagram
┌─────────────────────────────────────────────────────────────────┐
│ Splash Screen │
│ - Check for existing session │
│ - Initialize databases │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Has Valid Token │ │ No Token/ │
│ │ │ Token Expired │
└─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Main App │ │ Login Page │
│ (Timeline) │ │ │
└─────────────────┘ └─────────────────┘
Login Page UI
Screen Layout
┌─────────────────────────────────────┐
│ │
│ [Immich Logo] │
│ (animated) │
│ │
│ "immich" text │
│ │
├─────────────────────────────────────┤
│ Server URL │
│ ┌─────────────────────────────┐ │
│ │ https://your-server.com │ │
│ └─────────────────────────────┘ │
│ │
│ [Next Button] │
│ │
│ [Settings] │
│ │
├─────────────────────────────────────┤
│ v1.2.3 Logs │
└─────────────────────────────────────┘
After server validation:
┌─────────────────────────────────────┐
│ │
│ [Immich Logo] │
│ │
│ server-url.com │
│ │
├─────────────────────────────────────┤
│ Email │
│ ┌─────────────────────────────┐ │
│ │ user@example.com │ │
│ └─────────────────────────────┘ │
│ │
│ Password │
│ ┌─────────────────────────────┐ │
│ │ •••••••• │ │
│ └─────────────────────────────┘ │
│ │
│ [Login Button] │
│ ───────────── │
│ [OAuth Button] │
│ │
│ [Back] │
└─────────────────────────────────────┘
Server URL Validation
Process
- User enters server URL
- App sanitizes URL (adds https:// if missing, removes trailing slash)
- Attempts to resolve endpoint via
/.well-known/immich - Falls back to
{url}/apiif well-known not found - Pings server to verify reachability
- Stores validated URL locally
Well-Known Discovery
GET {server_url}/.well-known/immich
Response:
{
"api": {
"endpoint": "/api" // or absolute URL
}
}
Server Info Fetch
After URL validation, fetch server configuration:
GET /server/config
GET /server/features
This determines:
- Whether OAuth is enabled
- Whether password login is enabled
- OAuth button text
- Server version (for compatibility check)
Email/Password Login
API Request
POST /auth/login
Headers:
deviceModel: "iPhone 14 Pro" | "Pixel 7"
deviceType: "iOS" | "Android"
Body:
{
"email": "user@example.com",
"password": "secret123"
}
Response:
{
"accessToken": "eyJhbG...",
"userId": "uuid-here",
"userEmail": "user@example.com",
"name": "John Doe",
"isAdmin": false,
"shouldChangePassword": false,
"profileImagePath": "/path/to/image"
}
Post-Login Actions
- Store access token securely
- Store user info locally
- Generate/retrieve device ID
- Connect WebSocket for real-time updates
- Request gallery permissions
- Start initial sync
- Navigate to main app
OAuth Login (PKCE Flow)
Flow Diagram
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ App │ │ Server │ │ OAuth │ │ App │
│ │ │ │ │ Provider │ │ │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ 1. Request │ │ │
│ OAuth URL │ │ │
│───────────────►│ │ │
│ │ │ │
│ 2. Return URL │ │ │
│ + state │ │ │
│◄───────────────│ │ │
│ │ │ │
│ 3. Open Browser with code_challenge │
│────────────────────────────────►│ │
│ │ │ │
│ 4. User authenticates │ │
│ │ │ │
│ 5. Redirect with auth code │ │
│◄────────────────────────────────│ │
│ │ │ │
│ 6. Exchange code for token (with code_verifier) │
│───────────────►│ │ │
│ │ │ │
│ 7. Return access token │ │
│◄───────────────│ │ │
PKCE Parameters
- code_verifier: Random 43-128 character string
- code_challenge: SHA256 hash of verifier, base64url encoded
- state: Random 32 character string for CSRF protection
OAuth Request
GET /oauth/authorize?
code_challenge={code_challenge}&
code_challenge_method=S256&
state={state}
Response:
{
"url": "https://oauth-provider.com/auth?client_id=..."
}
OAuth Callback
POST /oauth/callback
Body:
{
"url": "immich://oauth-callback?code=xxx&state=yyy",
"codeVerifier": "original_code_verifier"
}
Response:
{
"accessToken": "eyJhbG...",
"userId": "uuid-here",
...
}
Session Management
Access Token Storage
- Stored in secure/encrypted storage
- Token included in all API requests via header
- Automatically loaded on app start
Request Authentication
All authenticated requests include:
Headers:
Authorization: Bearer {access_token}
x-immich-user-token: {access_token} // alternative
Token Validation
On app start:
- Load stored token
- Call
GET /users/meto validate - If valid, proceed to app
- If invalid (401), redirect to login
Logout
Process
- Call server logout endpoint
- Clear local access token
- Clear user data from database
- Disable background backup
- Cancel ongoing sync operations
- Navigate to login screen
API Request
POST /auth/logout
Data Cleared on Logout
- Access token
- Current user info
- Asset ETag (sync marker)
- Auto endpoint switching settings
- Preferred WiFi name
- Local/external endpoint list
Password Change
If shouldChangePassword is true after login:
- Redirect to Change Password screen
- User enters new password
- Submit password change
PUT /auth/change-password
Body:
{
"password": "newSecurePassword123"
}
Multi-Server Support
Automatic Endpoint Switching
The app can automatically switch between local and external server URLs based on WiFi network:
- Configure local endpoint (e.g.,
http://192.168.1.100:2283) - Configure external endpoint (e.g.,
https://photos.example.com) - Set preferred WiFi network name
- When on preferred WiFi, use local endpoint
- Otherwise, use external endpoint
Auxiliary Endpoint Validation
Before switching, validate the new endpoint is reachable:
GET {endpoint}/users/me
Response: 200 OK = valid endpoint
PIN Code / Local Auth
For the locked folder feature:
- User can set up a PIN code
- PIN is stored securely on device
- Biometric authentication can be used as alternative
PIN Setup
PUT /auth/pin-code
Body:
{
"pinCode": "1234"
}
PIN Verification
POST /auth/pin-code/verify
Body:
{
"pinCode": "1234"
}
Error Handling
Common Login Errors
| Error | User Message | Cause |
|---|---|---|
| Invalid URL | "Invalid server URL" | Malformed URL entered |
| Server unreachable | "Server is not reachable" | Network issue or wrong URL |
| SSL Error | "SSL certificate error" | Self-signed cert not trusted |
| Invalid credentials | "Login failed" | Wrong email/password |
| OAuth failed | "OAuth login failed" | OAuth flow interrupted |
| API exception | Error message from server | Server-side error |
Validation Rules
- URL: Must be valid URL with http/https scheme
- Email: Must contain @, no leading/trailing spaces
- Password: No specific validation (server handles it)
Version Compatibility
After connecting to server, check version compatibility:
- Get app version
- Get server version from
/server/version - Compare major/minor versions
- Show warning if mismatch detected