@imiobe/waco
v1.0.0
Published
Connexion Wallonie Connect (Keycloak OIDC) pour les apps Next.js d'iMio
Keywords
Readme
@imiobe/waco
Connexion Wallonie Connect (Keycloak OIDC) pour les apps Next.js d'iMio. Un projet pose
six variables d'environnement, une route et son proxy.ts ; il connaît ensuite l'état
de connexion par getSession().
Avoir une session, c'est être autorisé : le groupe éventuel est vérifié une fois, au retour de Keycloak. Après, seule la présence du cookie compte.
Installer
npm install @imiobe/wacoLe paquet est public sur npmjs : ni .npmrc, ni token, y compris dans le build Docker.
Brancher
// app/auth/[...waco]/route.ts — /auth/login, /auth/callback, /auth/logout, /auth/session
export { GET, POST } from '@imiobe/waco/handlers';// proxy.ts — toute l'app derrière Wallonie Connect
export { proxy } from '@imiobe/waco/proxy';
export const config = { matcher: ['/((?!healthz|_next/static|_next/image|favicon.ico).*)'] };// proxy.ts — seulement certaines routes
import { wacoProxy } from '@imiobe/waco/proxy';
export const proxy = wacoProxy({ isProtected: (pathname) => pathname.startsWith('/membres') });// côté serveur
import { getSession, loginHref, requireSession } from '@imiobe/waco';
const session = await getSession(); // { sub, name, email, groups } | null
await requireSession('/membres'); // redirige vers la connexion, puis revient sur /membres
<a href={loginHref('/membres')}>Se connecter</a>
<form action="/auth/logout" method="post"><button>Se déconnecter</button></form>// composant client, sur une page pré-rendue : la session arrive après l'hydratation
'use client';
import { loginHref, useSession } from '@imiobe/waco/client';
const session = useSession(); // undefined pendant le chargement, puis WacoSession | nulluseSession() interroge GET /auth/session, qui renvoie la session sans l'id_token.
Lire le cookie côté serveur rendrait dynamique toute page qui affiche le header ; ainsi,
les pages restent pré-rendues.
Le proxy ne fait qu'un contrôle optimiste (il déchiffre le cookie, sans appeler
Keycloak). Une page dynamique qui sert des données réservées appelle aussi
requireSession().
Configurer
| Variable | Exemple |
| --------------------- | ------------------------------------------------ |
| WACO_ISSUER | https://<hôte>/realms/central |
| WACO_CLIENT_ID | imio-help-center |
| WACO_CLIENT_SECRET | depuis Vault |
| WACO_REQUIRED_GROUP | délibérations.be — vide : tout le realm |
| WACO_SESSION_SECRET | openssl rand -base64 32, depuis Vault |
| APP_URL | https://aide.imio.be — l'URL publique de l'app |
Les variables sont lues à la première requête : next build n'en a pas besoin. Une
variable manquante fait échouer la requête, elle ne rend pas le visiteur anonyme.
Le client Keycloak
Même recette pour chaque app, dans le realm visé :
- client confidentiel, Standard flow seul, PKCE method
S256; - Valid redirect URIs :
${APP_URL}/auth/callback; - Valid post logout redirect URIs :
${APP_URL}/*; - mapper Group Membership sur le client : nom
groups, Full group path désactivé, Add to ID token activé.WACO_REQUIRED_GROUPse compare au nom tel quel.
Un second client, redirigé vers http://localhost:3000/auth/callback, sert au
développement.
Ce que le paquet fait, et ne fait pas
- La session dure 8 h. Un retrait de groupe ou un compte désactivé prend effet à la connexion suivante.
- Le cookie ne garde pas l'
access_token: pas d'appel d'API au nom de l'utilisateur. - L'
id_tokenest gardé pour la déconnexion (id_token_hint), sinon Keycloak demande confirmation. S'il fait dépasser au cookie la limite des navigateurs, il est abandonné et seule la confirmation revient. - Un émetteur en HTTP n'est accepté que sur
localhost.
Développer
npm install
npm test
npm run typecheck
npm run buildPour essayer contre un vrai Keycloak, quay.io/keycloak/keycloak en start-dev avec un
realm sslRequired: none et un client configuré comme ci-dessus suffit, puis
npm pack et installer l'archive dans une app Next.
Publier
npm version minor # ou patch, major — ne touche que package.json et le lockfile (cf. .npmrc)La version arrive sur main par une MR, et c'est tout : le job release publie sur npmjs
toute version qui n'y est pas encore (variable CI NPM_TOKEN), puis crée le tag X.Y.Z
et la release GitLab. Ne pas poser de tag à la main.
Une version majeure de Next est une version majeure du paquet.
