### IdNot – Flux agnostique du front (dev3 backend, dev4 frontend) Objectif: permettre à n'importe quel front (domaine inconnu, y compris localhost) d'utiliser l'auth IdNot sans modifier le redirect_uri déclaré chez IdNot. ### Vue d’ensemble - Le redirect_uri IdNot reste: `http://local.4nkweb.com:3000/authorized-client`. - Nginx sur dev3 intercepte ce host/port et redirige vers `https://dev3.4nkweb.com/idnot/callback` en conservant la query (`code`, `state`). - Le front demande au back un `state` signé contenant `next_url` (URL finale dynamique du front). - Le back valide `state`, échange le `code` chez IdNot, crée la session, puis 302 vers `next_url#authToken=<...>`. ### Composants - Backend (dev3, lecoffre-back-mini) - Frontend (dev4, lecoffre-front) - Nginx dev3: capte `local.4nkweb.com:3000/authorized-client` → `/idnot/callback` et proxy /api - Nginx dev4: sert `/lecoffre/` et proxifie `/api/` vers dev3 (inchangé pour ce flux) ### Variables d’environnement – Backend (dev3) Ajouter dans l’environnement du back: ```bash BACK_HMAC_SECRET= STATE_TTL_SECONDS=180 ALLOW_LOCALHOST_REDIRECTS=true ALLOWED_REDIRECT_HOST_PATTERNS=^dev4\.4nkweb\.com$,^localhost$,^127\.0\.0\.1$ ``` ### Implémentation – Backend (dev3) - Service de state `src/services/state.service.ts` - `signState(nextUrl: string)` → `{state}` - `verifyState(state: string)` → `{ next_url, nonce, ts }` - payload: `{ next_url, nonce, ts }` JSON - signature: `HMAC-SHA256(payload, BACK_HMAC_SECRET)` - TTL: `now - ts <= STATE_TTL_SECONDS` - Anti-rejeu: `Map` nettoyée périodiquement - Validation `next_url`: URL absolue; schéma https, ou http autorisé seulement si `ALLOW_LOCALHOST_REDIRECTS=true` et host ∈ {`localhost`, `127.0.0.1`}; host match `ALLOWED_REDIRECT_HOST_PATTERNS` - Handlers - `POST /api/v1/idnot/state` (body: `{ next_url }`) → 200 `{ state }` - `GET /idnot/callback` (query: `code`, `state`) - `verifyState(state)` → récupère `next_url` - `IdNotService.exchangeCodeForTokens(code)` (existant) - Crée la session/authToken - `302` vers `next_url#authToken=<...>` (fragment recommandé) - Erreurs: 400 (state invalide), 502 (échec IdNot), 400 (next_url invalide) - Routes à monter ```ts router.post('/api/v1/idnot/state', StateHandlers.createState) router.get('/idnot/callback', IdNotCallbackHandlers.callback) ``` ### Nginx – dev3 - Vhost capteur du redirect IdNot (ex: `/etc/nginx/sites-available/local.4nkweb.com-3000`) Avant: ```nginx return 301 https://dev4.4nkweb.com/lecoffre$request_uri; ``` Après: ```nginx return 301 https://dev3.4nkweb.com/idnot/callback$request_uri; ``` - Vhost principal dev3 (ex: `/etc/nginx/sites-available/dev3.4nkweb.com`) ```nginx location ^~ /api/ { proxy_pass http://127.0.0.1:8080; include /etc/nginx/proxy_params; } location = /idnot/callback { proxy_pass http://127.0.0.1:8080; include /etc/nginx/proxy_params; } ``` ### Variables d’environnement – Front (dev4) Ajouter au build/environnement front: ```bash NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED=http://local.4nkweb.com:3000/authorized-client NEXT_PUBLIC_BACK_BASE=https://dev3.4nkweb.com # Rappel API front (déjà en place) NEXT_PUBLIC_BACK_API_PROTOCOL=https NEXT_PUBLIC_BACK_API_HOST=dev4.4nkweb.com NEXT_PUBLIC_BACK_API_PORT=443 NEXT_PUBLIC_BACK_API_ROOT_URL=/api NEXT_PUBLIC_BACK_API_VERSION=v1 ``` ### Implémentation – Front (dev4) - Exposition des variables (next.config.js) - `NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED`, `NEXT_PUBLIC_BACK_BASE` - VariablesFront.ts - Ajouter `IDNOT_REDIRECT_URI_FIXED?: string;` - Ajouter `BACK_BASE?: string;` - Démarrage IdNot (ex: `StepEmail/index.tsx`) 1) `POST ${BACK_BASE}/api/v1/idnot/state` avec `{ next_url: window.location.origin + '/authorized-client' }` 2) Récupérer `{ state }` 3) Construire l’URL IdNot avec: - `redirect_uri=${NEXT_PUBLIC_IDNOT_REDIRECT_URI_FIXED}` - `state=${state}` - `client_id`, `scope`, `response_type=code` - Retour (page `authorized-client`) - Lire `#authToken` dans le fragment - Stocker cookie `leCoffreAccessToken` - Nettoyer le hash ### Sécurité - Pas d’open redirect: HMAC + TTL + nonce + whitelist host - `#authToken` dans le fragment pour éviter logs/proxys - Rate-limit sur `POST /api/v1/idnot/state` - Logs: ne pas exposer `next_url` complet ### Séquence (texte) 1) Front → Back: POST `/api/v1/idnot/state` body `{ next_url }` 2) Back → Front: `{ state }` 3) Front → IdNot: `/authorize?client_id=...&redirect_uri=http://local.4nkweb.com:3000/authorized-client&state=...` 4) IdNot → dev3 Nginx: `http://local.4nkweb.com:3000/authorized-client?code&state` 5) Nginx dev3 → Back: `GET /idnot/callback?code&state` 6) Back → IdNot: échange de token; session 7) Back → Front: `302 next_url#authToken=...` 8) Front: stocke token, poursuit navigation ### Tests - `POST https://dev3.4nkweb.com/api/v1/idnot/state` → 200, `{ state }` - `GET https://dev3.4nkweb.com/idnot/callback?code=&state=` → 302 vers `next_url#authToken=...` - Front: bouton IdNot → parcours complet → session active ### Points d’attention - Ajouter les domaines requis dans `ALLOWED_REDIRECT_HOST_PATTERNS` - TTL court (180s) et purge des nonces - En prod, préférer cookies sécurisés et durées minimales