This is an old revision of the document!
Table of Contents
OAuth2 / OIDC SSO System (SPA + Mobile + Web + PKCE + JWT + JWKS)
System Overview
We have:
SPA Client: vue-app.com
Mobile App: iOS / Android
Server A: crm.company.com
Server B: orders.company.com
SSO / Identity Provider: auth.company.com
SSO is the central authentication authority.
Key Concepts
SSO responsibilities:
User authentication (login) Authorization code issuance JWT token issuance Signing tokens with private key
Applications responsibilities:
Exchange authorization code (if applicable) Verify JWT using public key (JWKS) Manage local session (optional)
๐ Cryptography Model
SSO (Identity Provider):
PRIVATE KEY โ signs JWT (RS256)
Applications (Server A / B):
PUBLIC KEY (JWKS) โ verify JWT signature
=========================
CLIENT TYPES (IMPORTANT)
=========================
There are 3 types of clients:
1. Confidential Client (Server-side Web App)
Example:
Laravel / Spring / Django backend
Flow:
Backend exchanges code Backend stores session cookie
2. Public Client (SPA)
Example:
Vue.js / React.js
Flow:
Browser exchanges code Uses PKCE Stores JWT
3. Public Client (Mobile App)
Example:
iOS / Android apps
Flow:
App uses system browser login Uses PKCE Stores JWT in secure storage
=========================
PKCE FLOW (COMMON LOGIC)
=========================
Used by SPA + Mobile.
Step 1: Generate PKCE
Client generates:
code_verifier = random_secret
Then derives:
code_challenge = BASE64URL(SHA256(code_verifier))
Step 2: Redirect to SSO
GET https://auth.company.com/authorize
Parameters:
response_type=code client_id redirect_uri code_challenge code_challenge_method=S256 state
Step 3: User Login
User authenticates:
username/password MFA optional
SSO creates session:
SSO_SESSION=123
SSO sets cookie (browser only):
Set-Cookie: SSO_SESSION=123; Domain=auth.company.com
Step 4: Authorization Code Returned
302 โ redirect_uri?code=abc&state=xyz
โ code is short-lived โ code is one-time use
Step 5: Code Exchange
SPA / Mobile
POST https://auth.company.com/token
Request:
code=abc code_verifier=random_secret client_id=xxx
Server-side Web App
Server A โ POST /token
๐ PKCE VERIFICATION
SSO performs:
SHA256(code_verifier)
Compare:
SHA256(code_verifier) == code_challenge
โ match โ valid โ mismatch โ reject
=========================
JWT ISSUANCE
=========================
SSO returns:
access_token (JWT) id_token (JWT) refresh_token
๐ JWT SIGNING (SSO SIDE)
PRIVATE KEY โ signs JWT (RS256)
โ only SSO has private key โ tokens cannot be forged
=========================
JWT VERIFICATION
=========================
Servers (A / B) do:
Step 1: Fetch JWKS
GET https://auth.company.com/.well-known/jwks.json
Step 2: Verify signature
PUBLIC KEY โ validate JWT signature
Step 3: Validate claims
exp (expiration) iss (issuer) aud (audience) sub (user id)
โ valid โ allow request โ invalid โ reject
=========================
SPA FLOW
=========================
Step 1
User opens SPA:
vue-app.com
Step 2
Generate PKCE โ redirect to SSO
Step 3
Receive code โ exchange via browser JS
Step 4
Store access_token
Step 5
Call APIs:
Authorization: Bearer JWT
=========================
MOBILE FLOW
=========================
Step 1
App opens system browser:
auth.company.com
Step 2
Login โ SSO session created
Step 3
Redirect via deep link:
myapp://callback?code=abc
Step 4
App exchanges code using PKCE
Step 5
Store token in:
iOS Keychain Android Keystore
=========================
SERVER-SIDE WEB FLOW
=========================
Step 1
Browser โ Server A
Step 2
Server A redirects to SSO
Step 3
Server A exchanges code
Step 4
Server A creates session:
SESSION_A=aaa
=========================
KEY SECURITY MODEL
=========================
SSO:
issues authorization code signs JWT with PRIVATE KEY
Clients:
SPA/Mobile generate PKCE Server-side exchanges code
Servers:
verify JWT using PUBLIC KEY (JWKS) remain stateless
=========================
KEY INSIGHT
=========================
PKCE protects authorization code interception JWT ensures stateless authentication JWKS enables distributed verification SSO is single source of identity
=========================
FINAL INTERVIEW SUMMARY
=========================
OAuth2/OIDC with PKCE is a secure authentication mechanism used across SPA, mobile, and server-side applications. Public clients (SPA and mobile) use PKCE to securely exchange authorization codes for JWT tokens, while confidential clients (server-side apps) perform the exchange on the backend. The identity provider (SSO) signs JWT tokens using a private key, and all services verify them using public keys obtained from JWKS. This enables stateless, scalable authentication across distributed systems.
