Authentication Flows
Optare supports multiple OAuth 2.0 flows. Choose the right one for your application type.
Flow Selection Guide
| Application Type | Recommended Flow |
|---|---|
| SPA (React, Vue) | Authorization Code + PKCE |
| Server-Side Web App | Authorization Code |
| Mobile App | Authorization Code + PKCE |
| Backend Service (M2M) | Client Credentials |
| Device (TV, CLI) | Device Authorization |
Authorization Code Flow (with PKCE)
Best for: SPAs, Mobile Apps, any public client
The most secure flow for user-facing applications.
┌──────────┐ ┌───────────┐ ┌──────────┐
│ Browser │ │ Optare │ │ Your API │
└────┬─────┘ └─────┬─────┘ └────┬─────┘
│ │ │
│ 1. Generate PKCE verifier/challenge
│ │ │
│ 2. Redirect to Optare ──────────►│
│ │ │
│◄──── 3. User logs in ────────────│
│ │ │
│ 4. Redirect with code ◄──────────│
│ │ │
│ 5. Exchange code + verifier ────►│
│ │ │
│◄──── 6. Access + Refresh tokens ─│
│ │ │
│ 7. Call API with token ─────────────────►│Implementation
// 1. Generate PKCE
const verifier = generateCodeVerifier();
const challenge = await generateCodeChallenge(verifier);
// 2. Redirect to authorize
const params = new URLSearchParams({
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
response_type: 'code',
scope: 'openid profile email',
code_challenge: challenge,
code_challenge_method: 'S256',
});
window.location.href = `${OPTARE_DOMAIN}/oauth/authorize?${params}`;
// 4. Exchange code for tokens (in callback)
const tokens = await fetch('/oauth/token', {
method: 'POST',
body: JSON.stringify({
grant_type: 'authorization_code',
code: authorizationCode,
code_verifier: verifier,
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
}),
});Authorization Code Flow (Confidential Client)
Best for: Server-side web apps with a backend
┌──────────┐ ┌──────────┐ ┌───────────┐
│ Browser │ │ Server │ │ Optare │
└────┬─────┘ └────┬─────┘ └─────┬─────┘
│ │ │
│ 1. Click login │ │
│───────────────►│ │
│ │ 2. Redirect ────►
│◄────────────────────────────────────────
│ 3. User logs in at Optare │
│─────────────────────────────────►│
│◄──── 4. Redirect with code ──────│
│───────────────►│ │
│ │ 5. Exchange code│
│ │ + client_secret│
│ │────────────────►│
│ │◄─── 6. Tokens ──│
│◄─ 7. Set cookie│ │Implementation
// Server-side token exchange
const tokens = await fetch(`${OPTARE_DOMAIN}/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
code: code,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET, // Server-side only!
redirect_uri: REDIRECT_URI,
}),
});Client Credentials Flow
Best for: Machine-to-machine (M2M), backend services, cron jobs
No user involved - the application authenticates itself.
┌──────────┐ ┌───────────┐
│ Service │ │ Optare │
└────┬─────┘ └─────┬─────┘
│ │
│ 1. Request token│
│ client_id + │
│ client_secret │
│────────────────►│
│ │
│◄─ 2. Access token
│ │
│ 3. Call API ────────────────►Implementation
const response = await fetch(`${OPTARE_DOMAIN}/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.SERVICE_CLIENT_ID,
client_secret: process.env.SERVICE_CLIENT_SECRET,
audience: 'https://api.myapp.com',
}),
});
const { access_token } = await response.json();Refresh Token Flow
Best for: Maintaining sessions without re-authentication
┌──────────┐ ┌───────────┐
│ App │ │ Optare │
└────┬─────┘ └─────┬─────┘
│ │
│ Access token │
│ expired │
│ │
│ 1. Send refresh │
│ token │
│────────────────►│
│ │
│◄─ 2. New access │
│ + refresh │
│ tokens │Implementation
const response = await fetch(`${OPTARE_DOMAIN}/oauth/token`, {
method: 'POST',
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: storedRefreshToken,
client_id: CLIENT_ID,
}),
});Device Authorization Flow
Best for: TVs, CLI tools, devices without browsers
┌──────────┐ ┌───────────┐ ┌──────────┐
│ Device │ │ Optare │ │ Phone │
└────┬─────┘ └─────┬─────┘ └────┬─────┘
│ │ │
│ 1. Get code ───►│ │
│◄─ device_code, │ │
│ user_code │ │
│ │ │
│ 2. Show code │ │
│ "Enter ABC123"│ │
│ │ │
│ │◄─ 3. User enters
│ │ code │
│ │ │
│ 4. Poll ───────►│ │
│◄─ access_token ─│ │Security Best Practices
| Practice | Description |
|---|---|
| Always use PKCE | Even for confidential clients |
| Short token lifetimes | 15 min - 1 hour for access tokens |
| Rotate refresh tokens | Issue new refresh token on use |
| Validate tokens server-side | Check iss, aud, exp claims |
| Use httpOnly cookies | For refresh tokens in web apps |
Next Steps
- Tokens Explained - Understand token types
- B2B Architecture - Design patterns
- Security Model - Security deep dive