5.2 KiB
5.2 KiB
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é contenantnext_url
(URL finale dynamique du front). - Le back valide
state
, échange lecode
chez IdNot, crée la session, puis 302 versnext_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:
BACK_HMAC_SECRET=<random-long-hex>
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<nonce, expiry>
nettoyée périodiquement - Validation
next_url
: URL absolue; schéma https, ou http autorisé seulement siALLOW_LOCALHOST_REDIRECTS=true
et host ∈ {localhost
,127.0.0.1
}; host matchALLOWED_REDIRECT_HOST_PATTERNS
-
Handlers
POST /api/v1/idnot/state
(body:{ next_url }
) → 200{ state }
GET /idnot/callback
(query:code
,state
)verifyState(state)
→ récupèrenext_url
IdNotService.exchangeCodeForTokens(code)
(existant)- Crée la session/authToken
302
versnext_url#authToken=<...>
(fragment recommandé)- Erreurs: 400 (state invalide), 502 (échec IdNot), 400 (next_url invalide)
-
Routes à monter
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:
return 301 https://dev4.4nkweb.com/lecoffre$request_uri;
Après:
return 301 https://dev3.4nkweb.com/idnot/callback$request_uri;
- Vhost principal dev3 (ex:
/etc/nginx/sites-available/dev3.4nkweb.com
)
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:
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;
- Ajouter
- Démarrage IdNot (ex:
StepEmail/index.tsx
)POST ${BACK_BASE}/api/v1/idnot/state
avec{ next_url: window.location.origin + '/authorized-client' }
- Récupérer
{ state }
- 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
- Lire
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)
- Front → Back: POST
/api/v1/idnot/state
body{ next_url }
- Back → Front:
{ state }
- Front → IdNot:
/authorize?client_id=...&redirect_uri=http://local.4nkweb.com:3000/authorized-client&state=...
- IdNot → dev3 Nginx:
http://local.4nkweb.com:3000/authorized-client?code&state
- Nginx dev3 → Back:
GET /idnot/callback?code&state
- Back → IdNot: échange de token; session
- Back → Front:
302 next_url#authToken=...
- 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=<réel>&state=<state>
→ 302 versnext_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