GeoLeaf — Authentification HTTP avec @geoleaf/connector
Package : @geoleaf/connectorVersion : 2.0.0 Licence : MIT — distribué sur npmjs.orgDernière mise à jour : mars 2026
Vue d'ensemble
@geoleaf/connector est un plugin MIT qui ajoute une couche d'authentification transparente à GeoLeaf. Il intercepte toutes les requêtes fetch (GeoJSON, WFS, REST) et injecte automatiquement un header Authorization: Bearer <token>.
Cas d'usage principal : protéger vos données cartographiques derrière une authentification sans modifier le code de chargement des couches.
Fonctionnalités :
- Monkey-patch
window.fetch— toutes les requêtes versbaseUrlreçoivent le header - JWT : détection d'expiration + refresh automatique
- Persistance du token en IndexedDB (survit au rechargement de page)
- Modal de connexion accessible (aucune dépendance CSS externe)
- Intercept MapLibre
transformRequestpour les tuiles vectorielles (MVT/PMTiles)
Installation
npm install @geoleaf/connectorPrérequis :
@geoleaf/core≥ 2.0.0 (peer dependency).
Intégration avec GeoLeaf
Le connector doit être importé après @geoleaf/core et configuré avant GeoLeaf.boot() :
import "@geoleaf/core";
import "@geoleaf/connector";
await GeoLeaf.Connector.configure({
baseUrl: "https://api.example.com",
getToken: () => localStorage.getItem("my-token"),
});
GeoLeaf.init({
map: { target: "map" },
data: {
activeProfile: "mon-profil",
profilesBasePath: "./profiles/",
},
});
GeoLeaf.boot();En CDN :
<script type="module" src="https://unpkg.com/@geoleaf/core@2.0.0/dist/geoleaf.esm.js"></script>
<script type="module" src="geoleaf-connector.plugin.js"></script>
<script type="module">
await GeoLeaf.Connector.configure({
baseUrl: "https://api.example.com",
getToken: () => "MY_TOKEN",
});
GeoLeaf.init({ map: { target: "map" }, data: { activeProfile: "mon-profil" } });
GeoLeaf.boot();
</script>Scénarios d'utilisation
| Scénario | Configuration | Cas d'usage |
|---|---|---|
| S1 — Token statique | getToken: () => 'static' | Dev / smoke test sans serveur |
| S2 — Login modal + JWT | auth: { endpoint, ui: true } | Login modal + JWT + refresh auto (IDB) |
| S3 — SSO externe | getToken: () => localStorage.getItem(...) | Token existant géré par une autre lib |
| S4 — Provider async | getToken: async () => await myAuth.get() | Keycloak, Auth0, ou provider custom |
| S5 — Token silencieux | auth: { endpoint, ui: false } | Token pré-chargé en IDB — pas de modal |
| S6 — Données publiques | getToken: () => 'STATIC_DEV_TOKEN' | Démo publique, données non sensibles |
S1 — Token statique (développement)
await GeoLeaf.Connector.configure({
baseUrl: "http://localhost:3000",
getToken: () => "MY_DEV_TOKEN",
});Un
console.warnest émis si le token ne contient pas.(non-JWT). Normal en mode dev.
S2 — Authentification avec modal de connexion
await GeoLeaf.Connector.configure({
baseUrl: "https://api.example.com",
auth: {
endpoint: "https://api.example.com/auth/login",
ui: true, // affiche une modal si aucun token valide en IDB
},
});Le connector vérifie d'abord IndexedDB. Si aucun token valide n'est trouvé, la modal de connexion s'affiche. Le token obtenu est persisté en IDB et rafraîchi automatiquement avant expiration.
S4 — Provider async (Keycloak, Auth0)
await GeoLeaf.Connector.configure({
baseUrl: "https://api.example.com",
getToken: async () => {
const token = await keycloak.updateToken(30);
return keycloak.token;
},
});API
GeoLeaf.Connector.configure(config)
await GeoLeaf.Connector.configure({
baseUrl: "https://api.example.com", // Toutes les requêtes vers ce domaine seront interceptées
getToken: () => "JWT_TOKEN", // Fonction synchrone ou async retournant le token
// — OU —
auth: {
endpoint: "https://api.example.com/auth/login", // Endpoint login (POST)
ui: true, // true → modal si absent | false → silencieux
},
});createConnector(config) — export nommé ESM
Pour les cas d'intégration avancés (tests unitaires, usage sans namespace global) :
import { createConnector } from "@geoleaf/connector";
const conn = createConnector({
baseUrl: "https://api.example.com",
getToken: () => "TOKEN",
});
const token = await conn.getTokenAsync();
conn.destroy(); // Retire les intercepteurs fetchÉvénements DOM
| Événement | Détail | Déclenché quand |
|---|---|---|
connector:authenticated | { baseUrl } | Login modal réussi |
connector:token-refreshed | { baseUrl } | Refresh automatique JWT |
connector:auth-error | { baseUrl, error } | 401 après tentative de refresh |
document.addEventListener("connector:authenticated", (e) => {
console.log("Authentifié sur", e.detail.baseUrl);
});
document.addEventListener("connector:auth-error", (e) => {
console.error("Échec auth", e.detail.error);
// Rediriger vers la page de connexion
});Sécurité
- Le token n'est jamais transmis en query string — uniquement via header
Authorization - Les mots de passe sont effacés de la mémoire après utilisation (OWASP A02)
baseUrldoit utiliser HTTPS en production (erreur levée sinon)- Sanitisation XSS de la modal :
textContentuniquement — aucuninnerHTMLavec données utilisateur - MVT / PMTiles : interceptés via
map.setTransformRequest()(MapLibre bridge), pas viawindow.fetch
Vérification du chargement
GeoLeaf.PluginRegistry.isLoaded("connector"); // → true / false
GeoLeaf.PluginRegistry.getInfo("connector");
// → { name: "connector", version: "2.0.0", loaded: true, label: "Connector (Auth + Fetch intercept)" }Documentation complète
Pour les options avancées, le détail de l'architecture interne, les tests et le build :
→ packages/plugin-connector/README.md
Voir aussi
- PLUGIN_DEVELOPMENT_GUIDE.md — développer un plugin custom
- PLUGIN_CONFIGURATION_GUIDE.md — configuration des plugins dans un profil
- GETTING_STARTED.md — démarrage rapide
