Choosing the right flow
Decision tree
┌─────────────────────────────┐
│ What kind of application? │
└─────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Server-side web │ │ SPA / mobile │ │ Backend service │
│ application │ │ application │ │ (no user) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Authorization │ │ Authorization │ │ Client │
│ Code Flow │ │ Code + PKCE │ │ Credentials │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Flow comparison
| Feature | Auth Code | Auth Code + PKCE | Client Credentials |
|---|---|---|---|
| User authentication | Yes | Yes | No |
| Refresh tokens | Yes | Yes | No |
| Requires a client secret | Yes | No | Yes |
| Suitable for frontends | No | Yes | No |
| User consent | Yes | Yes | No |
| Returns an ID token | Yes | Yes | No |
Recommendations by application type
| Application type | Recommended flow | Notes |
|---|---|---|
| Traditional web app (PHP, Rails, Django, ASP.NET) | Authorization Code | Store tokens on the server |
| Single Page Application (React, Vue, Angular) | Authorization Code + PKCE | No backend required |
| Mobile app (iOS, Android) | Authorization Code + PKCE | Use a custom URL scheme |
| Native desktop application | Authorization Code + PKCE | Use a localhost redirect |
| Backend service / cron job | Client Credentials | No user context |
| Microservice-to-microservice communication | Client Credentials | Service-account access |
Quick summary
- Do you have a backend that can keep secrets? → Authorization Code Flow
- An SPA or mobile app? → Authorization Code + PKCE
- No user involved (M2M)? → Client Credentials