You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
8.**RFC9700 - Best Current Practice for OAuth 2.0 Security**: https://datatracker.ietf.org/doc/rfc9700/
31
+
9.**OAuth 2.0 Security (inspired from RFC-9700)**: https://workos.com/blog/oauth-common-attacks-and-how-to-prevent-them
32
+
10.**OAuth 2.0 for Browser-Based Applications (2026) (derived from RFC9700)**: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps
31
33
32
34
## OIDC Flows
33
35
34
-
Some OAuth 2.0 flows (e.g. [Implicit Flow (token leakage)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10#name-removal-of-the-oauth-20-imp), [Resource Owner Password Credentials grant (ROPC)(no MFA support)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10#name-differences-from-oauth-20)), or Auth Code Flow without PKCE, have already been deprecated as per OAuth 2.1, below are the recommended flows in 2025:
| ❌Deprecated Implicit Flow | SPA, native apps, desktop, mobile |`token` or `id_token` or `code id_token`, etc. | ⚠️Access token exposed in browser URL |
39
+
| ❌Deprecated Resource Owner Password Credentials grant | SPA, native apps, desktop, mobile | — (direct `/token`, no `/authorize`) | U⚠️ser password is given to unsecure client App, but not Identity Provider |
40
+
| ❌Deprecated Authorization Code Flow without PKCE | SPA, native apps, desktop, mobile |`code`| ⚠️Without code_verifier from PKCE, Identity Provider cannot verify the auth code sent to `/token` is from the original client |
| Client Credentials Flow | Non-interactive Machine-to-machine | — (direct `/token`, no `/authorize`) | No user involved |
44
+
| Device Authorization Flow (Device Code) | Half-interactive TVs, CLI apps, IoT | — (POST `/device`, user enters `user_code`) | User logs in on separate device.<br/>Useful when no browser available or with limited input capabilities.<br/>e.g. <https://microsoft.com/devicelogin>|
| Authorization Code Flow + PKCE (Public Client) | SPA, native apps, desktop, mobile | No client_secret, uses PKCE |
40
-
| Client Credentials Flow | Machine-to-machine | No user involved |
41
-
| Device Authorization Flow (Device Code) | TVs, CLI apps, IoT | User logs in on separate device.<br/>Useful when no browser available or with limited input capabilities.<br/>e.g. <https://microsoft.com/devicelogin>|
46
+
### Deprecated Implicit Flow
47
+
48
+
1. Initiated by : `GET /authorize?response_type=token&...`, some vendors use `response_type=id_token token&...`.
49
+
2. ❌IdP returns tokens directly in URL fragment (`&access_token=...&...`), which is exposed to browser history, referrers, and potentially malicious scripts.
### Deprecated Authorization Code Flow without PKCE (Public Client) for SPA
104
+
105
+
Same as below [Authorization Code Flow + PKCE (Public Client) for SPA](#authorization-code-flow--pkce-public-client-for-spa), but **without**`code_verifier` provided by PKCE (Proof Key for Code Exchange).
106
+
107
+
Because the Authorization Code Flow hands the code through the unsecure browser's front channel, an untrusted path, an attacker who intercepts that code can replay it at `/token` and steal tokens ([Authorization Code Injection](https://www.thehacker.recipes/web/config/identity-and-access-management/oauth-2.0#authorization-code-injection)). PKCE prevents this: the SPA generates a `code_verifier`, keeps it secret, and later submits it over the secure back channel, enabling the Identity Provider to confirm that the caller exchanging the code (by `POST /token`) is the same client that initiated `GET /authorize`.
42
108
43
109
### Authorization Code Flow + PKCE (Public Client) for SPA
44
110
@@ -53,6 +119,8 @@ With **PKCE** (Proof Key for Code Exchange), **Authorization Code Injection atta
53
119
54
120
**OIDC Authorization Code Flow with PKCE for SPA:**
55
121
122
+
Initiated by : `GET /authorize?response_type=code&...`
IdP ->> SPA: access_token(aud=https://my-downstream-api)<br/>id_token(sub="alice", nonce=N123)<br/>refresh_token(optional with rotation or often disabled for SPAs)
132
200
133
201
%% SPA verifies nonce
134
202
SPA ->> SPA: Validate id_token.nonce == N123 ?
@@ -201,8 +269,6 @@ Once the user is authenticated, the BFF can use multiple methods to obtain acces
201
269
|**API Keys**| Same as mTLS but with API key<br/>Legacy / simple | ❌ No | ✔ OK | ❌ No |
202
270
|**Internal Headers / Cookies**| Service mesh | Optional (propagated) | ✔ Yes | ❌ No |
203
271
204
-
Below is an example sequence diagram illustrating the OIDC Authorization Code Flow with BFF pattern and session cookies, including the use of refresh tokens to obtain access tokens for multiple downstream APIs.
205
-
206
272
**OIDC Authorization Code Flow with stateful BFF pattern and refresh token grant for multiple Downstream APIs (API-1 and API-2):**
207
273
208
274
!!! note "the BFF flow could have many variations, below diagram is one of them"
The Device Authorization Flow (Device Code Flow) is designed for devices with limited input capabilities (e.g., smart TVs, IoT devices) where users cannot easily enter credentials, or for devices without interactive browser capabilities (e.g. CLI). Instead, the device displays a code that the user enters on a separate device (like a smartphone or computer) to authenticate.
400
+
401
+
```mermaid
402
+
sequenceDiagram
403
+
autonumber
404
+
participant User
405
+
participant DeviceApp as Device / TV App
406
+
participant AuthServer as Authorization Server
407
+
participant Browser as User Browser
408
+
participant API as Resource Server (API)
409
+
410
+
User->>DeviceApp: Open app (no browser / keyboard)
411
+
DeviceApp->>AuthServer: POST /device_authorization (client_id)
Session cookies are simpler for single-application scenarios, while OIDC is better suited for distributed systems, microservices, and multi-application environments where centralized authentication and SSO are needed.
@@ -860,3 +965,64 @@ sequenceDiagram
860
965
-**SAML** (Security Assertion Markup Language) is an older standard in **XML** for single sign-on (SSO) and identity federation, primarily used in enterprise environments, and **only for web-based applications**.
861
966
862
967
-**OIDC** is a more modern protocol in **JSON/REST** that is easier to implement and is designed for **web and mobile applications**, could be used for SSO too.
968
+
969
+
### SPA (Single Page Application) vs Multi-page applications (MPA) vs Web Apps vs Browser
SSR["Server-side Web App (SSR)<br/>(HTML rendered on server)"]
985
+
CSR["Client-side Web App (CSR)<br/>(HTML/UI rendered in browser via JS)"]
986
+
end
987
+
988
+
%% Relationships: Browser <-> Web App
989
+
Browser -->|"loads & runs"| WebApp
990
+
991
+
%% Web App types
992
+
WebApp --> MPA
993
+
WebApp --> Hybrid
994
+
WebApp --> SPA
995
+
996
+
%% Rendering models
997
+
MPA -->|"typically"| SSR
998
+
SPA -->|"typically"| CSR
999
+
1000
+
Hybrid -.->|"1️⃣initial load"| SSR
1001
+
Hybrid -.->|"2️⃣after hydration"| CSR
1002
+
1003
+
style Browser fill:#e1f5ff
1004
+
style WebApp fill:#fff4e1
1005
+
style MPA fill:#f0f0f0
1006
+
style SPA fill:#f0f0f0
1007
+
style Hybrid fill:#e8f5e9
1008
+
```
1009
+
1010
+
**Core Terms (Architecture & Client):**
1011
+
1012
+
-**Web App (SPA + MPA)**: A broader term that encompasses any application accessed via a web browser, including SPAs, multi-page applications (MPAs), and server-rendered applications. Web apps can vary in complexity and architecture.
1013
+
-**Browser**: The software application (e.g., Chrome, Firefox, Safari) that users utilize to access web apps (SPA or MPA). The browser handles rendering HTML, executing JavaScript, managing cookies, and facilitating communication between the client and server.
1014
+
1015
+
**Rendering Location:**
1016
+
1017
+
-**Server-side Web App (SSR)**: The application's UI is generated and assembled into full HTML on the server before being sent to the browser. **Traditional Web Apps (MPAs)** are typically Server-side Web Apps.
1018
+
-**Client-side Web App (CSR)**: The server sends minimal HTML and JavaScript, and the UI is **dynamically generated in the browser** using that JavaScript. **SPAs** are typically Client-side Web Apps.
1019
+
1020
+
| Feature | Traditional Web App (MPA) | Single Page Application (SPA) | Modern Hybrid (Next.js, Nuxt.js, Remix, SvelteKit…) |
| Primary Rendering | Server-Side Rendering (SSR) | Client-Side Rendering (CSR) | ✅SSR/SSG for initial request,<br/>then CSR after hydration (often with React/Vue/Svelte Server Components where applicable) |
1023
+
| Data Flow | Full HTML page <- Server | HTML shell + JS bundle <- Server; data (JSON) via API | HTML + data pre-rendered on server (SSR/SSG) <- Server<br/>then JSON/API or loader-based data for client-side navigation |
1024
+
| Page Loads | Full page reload on every navigation | ✅No full page reload; DOM updated dynamically | First load: full HTML from server; ✅subsequent navigations use client-side routing (SPA-like, no full reload) |
1025
+
| SEO | ✅Very good (content rendered on server, already available for crawlers) | Harder by default; better with SSR, SSG, pre-rendering, or hydration | ✅Excellent when using SSR/SSG: crawlers see full HTML; good Core Web Vitals with caching/CDN/edge rendering |
1026
+
| Initial Load | ✅Often fast (server sends ready-to-render HTML) | Often slower (must download + parse + execute JS bundle before rendering)| ✅Fast and SEO-friendly: pre-rendered HTML + critical data; JS hydrates progressively in the background |
1027
+
| Post-Load UX | Slower (each action may trigger a full reload)<br/>could be improved with caching/CDN | ✅Very fast / app-like (client-side routing and state) | ✅SPA-like UX after hydration: fast client-side transitions + server/data caching strategies |
1028
+
| Typical Stacks | Django, Flask + Jinja (Python), Laravel (PHP), Ruby on Rails, Express (Node.js) with templates, ASP.NET | Frontend (JS): React, Vue, Angular, Svelte, etc. consuming APIs (any languages) | Next.js (React), Nuxt.js (Vue), Remix (React), SvelteKit (Svelte), Astro (multi-framework), Qwik City, etc. |
0 commit comments