OculusCyber Logo

OculusCyber

Home

Browse Topics


Hilton Login → Hilton Auth Server → Backend → Booking API (OAuth PKCE flow)

By Admin

November 15, 2025


Hilton Login → Hilton Auth Server → Backend → Booking API

With PKCE, annotations, and user actions shown.

Here is the corrected and updated flow, with the missing step added clearly showing WHERE the frontend sends the code_verifier to the backend.

IMPORTANT:Step 7 must include BOTH:

  • authorization_code
  • code_verifier

Otherwise the backend cannot complete Step 8.

I have updated Step 7 to include this.

UPDATED + CORRECTED FULL FLOW WITH code_verifier SENT TO BACKEND

┌─────────────────────────────────────────────────────────────┐
│                       0. HILTON WEBSITE                     │
│                  (User just browsing normally)              │
│            ❌ No PKCE generated at this point               │
└─────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 1. USER CLICKS "LOGIN" or "VIEW RESERVATIONS"                        │
│    ✔ This action STARTS the OAuth login flow                         │
│    ✔ This is when PKCE must be generated                             │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 2. FRONTEND (React/Vue/JS) GENERATES PKCE                            │
│   ✔ code_verifier = random 43–128 chars                              │
│   ✔ code_challenge = SHA256(code_verifier)                           │
│   ✔ code_verifier stored in memory/sessionStorage on frontend        │
│                                                                      │
│   ⚠ Backend DOES NOT know code_verifier yet                          │
│   PKCE is always generated inside the browser                        │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 3. FRONTEND REDIRECTS BROWSER TO AUTH SERVER                         │
│      GET https://login.hilton.com/authorize?                         │
│         client_id=hilton-app                                         │
│         response_type=code                                            │
│         code_challenge=XYZ123  (sent here)                            │
│         code_challenge_method=S256                                    │
│         redirect_uri=https://app.hilton.com/callback                  │
│                                                                      │
│   ✔ Front-channel browser redirect                                   │
│   ✔ SAFE to send code_challenge (hash; cannot be reversed)           │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 4. AUTH SERVER SHOWS LOGIN PAGE                                      │
│ 5. USER ENTERS CREDENTIALS                                           │
│                                                                      │
│   ✔ User interaction happens here                                    │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 6. AUTH SERVER REDIRECTS BROWSER BACK                                │
│     https://app.hilton.com/callback?code=AUTH_CODE_123               │
│                                                                      │
│   ✔ Browser receives ONLY authorization_code                         │
│   ✔ Browser still has code_verifier locally                          │
│   ✔ No tokens exposed                                                │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 7. FRONTEND SENDS BOTH TO BACKEND:                                  │
│                                                                      │
│   POST /exchange_code                                                │
│     {                                                                │
│       code: "AUTH_CODE_123",                                         │
│       code_verifier: "ORIGINAL_CODE_VERIFIER"   <── NEWLY ADDED      │
│     }                                                                │
│                                                                      │
│   ✔ THIS is the step where backend receives the code_verifier        │
│   ✔ code_verifier NEVER sent to auth server through browser          │
│   ✔ Still no tokens in the browser                                   │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 8. BACKEND SENDS TOKEN REQUEST TO AUTH SERVER                        │
│                                                                      │
│   POST https://login.hilton.com/token                                │
│     grant_type=authorization_code                                    │
│     code=AUTH_CODE_123                                               │
│     code_verifier=ORIGINAL_CODE_VERIFIER   <── Backend sends this    │
│     client_id=hilton-app                                             │
│     client_secret=xxxxx (confidential clients only)                  │
│                                                                      │
│   ✔ BACK-CHANNEL (server → server HTTPS)                             │
│   ✔ code_verifier now available because frontend sent it             │
│   ✔ Backend performs full PKCE binding                               │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 9. AUTH SERVER VALIDATES PKCE                                        │
│                                                                      │
│   SHA256(code_verifier) == code_challenge ?                          │
│                                                                      │
│   IF MATCH → returns tokens (BACK-CHANNEL ONLY):                     │
│     - access_token (JWT)                                             │
│     - refresh_token                                                  │
│     - id_token                                                       │
│                                                                      │
│   ✔ Tokens NEVER travel through browser                              │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 10. BACKEND CREATES SESSION COOKIE                                   │
│                                                                      │
│   ✔ Backend stores tokens securely                                   │
│   ✔ Browser gets only a secure HttpOnly cookie                       │
│   ✔ Browser NEVER handles access_token                               │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 11. BROWSER CALLS BACKEND FOR DATA                                   │
│                                                                      │
│     GET /my/reservations                                             │
│                                                                      │
│   ✔ Backend uses access_token to call Booking API                    │
└──────────────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ 12. BACKEND → BOOKING API USING ACCESS TOKEN                         │
│                                                                      │
│     GET /api/reservations                                            │
│     Authorization: Bearer <access_token>                             │
│                                                                      │
│   ✔ Resource server validates JWT and returns reservation data       │
└──────────────────────────────────────────────────────────────────────┘

FINAL SUMMARY

✔ The frontend generates PKCE.

✔ The frontend stores the code_verifier.

✔ The frontend sends both the authorization_code AND the code_verifier to the backend in Step 7.

✔ The backend uses the code_verifier during /token exchange (Step 8).

✔ Access/ID/Refresh tokens NEVER touch the browser.