Exemple de Validation JWT avec Node.js
⚠️ Avis Important : Ceci est un exemple basique à des fins de démonstration uniquement. Pour une utilisation en production, veuillez rechercher et mettre en œuvre les meilleures pratiques spécifiques à votre pile logicielle, vos exigences de sécurité et votre environnement de déploiement. Suivez toujours les directives de sécurité de votre organisation et envisagez d'utiliser des bibliothèques et frameworks JWT établis.
📝 Remarque : Cet exemple démontre le téléchargement de JWKS et la mise en cache de fichiers à des fins éducatives. Dans les environnements de production, vous pouvez choisir de gérer les clés JWKS différemment en fonction de votre infrastructure - comme utiliser la gestion de configuration, les variables d'environnement ou votre stratégie de mise en cache préférée.
Cet exemple démontre comment valider les jetons JWT de Rokt en utilisant Node.js.
Prérequis
Installez les paquets requis :
npm install jose jsonwebtoken
Exemple Complet
const { jwtVerify, importJWK } = require('jose');
const jwt = require('jsonwebtoken');
// Jeton JWT (JSON Web Token) d'exemple de Rokt
// Copiez le jeton de test depuis la page d'aperçu
const SAMPLE_JWT_TOKEN = "PASTE_TEST_TOKEN_HERE";
// URL du point de terminaison JWKS (JSON Web Key Set)
const JWKS_URL = "https://public-api.rokt.com/.well-known/jwks.json";
const JWKS_CACHE_FILE = "jwks_cache.json";
/**
* Valider le jeton JWT en utilisant la bibliothèque jose (recommandé)
*/
async function validateReferralTokenJose(jwtToken, jwksJson) {
try {
// Analyser JWKS
const jwks = typeof jwksJson === 'string' ? JSON.parse(jwksJson) : jwksJson;
if (!jwks.keys || jwks.keys.length === 0) {
throw new Error('Aucune clé trouvée dans JWKS');
}
// Obtenir la première clé
const jwk = jwks.keys[0];
// Importer JWK pour créer la clé publique
const publicKey = await importJWK(jwk, 'ES256');
// Vérifier et décoder le jeton JWT
const { payload } = await jwtVerify(jwtToken, publicKey, {
algorithms: ['ES256'],
clockTolerance: '1m' // Permettre un décalage d'horloge de 1 minute
});
return {
isValid: true,
campaignID: payload.cid,
creativeID: payload.crid,
rclid: payload.rclid,
issuedAt: new Date(payload.iat * 1000)
};
} catch (error) {
return {
isValid: false,
error: error.message
};
}
}
/**
* Implémentation alternative utilisant la bibliothèque jsonwebtoken
*/
function validateReferralTokenJWT(jwtToken, jwksJson) {
try {
// Analyser JWKS
const jwks = typeof jwksJson === 'string' ? JSON.parse(jwksJson) : jwksJson;
if (!jwks.keys || jwks.keys.length === 0) {
throw new Error('Aucune clé trouvée dans JWKS');
}
// Obtenir la première clé
const jwk = jwks.keys[0];
// Pour jsonwebtoken, vous devez convertir JWK en format PEM
// Ceci est un exemple simplifié - en pratique, vous auriez besoin d'une conversion JWK vers PEM appropriée
const publicKeyPem = `-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_PEM_HERE
-----END PUBLIC KEY-----`;
// Vérifier et décoder le jeton JWT
const decoded = jwt.verify(jwtToken, publicKeyPem, {
algorithms: ['ES256'],
clockTolerance: 60 // Permettre un décalage d'horloge de 1 minute
});
return {
isValid: true,
campaignID: decoded.cid,
creativeID: decoded.crid,
```javascript
rclid: decoded.rclid,
issuedAt: new Date(decoded.iat * 1000)
};
} catch (error) {
return {
isValid: false,
error: error.message
};
}
/**
* Fonction principale pour démontrer la validation de jeton
*/
async function downloadAndCacheJWKS(jwksUrl, cacheFile) {
const fs = require('fs');
const path = require('path');
// Vérifier si le fichier cache existe et est récent (moins de 24 heures)
if (fs.existsSync(cacheFile)) {
const stats = fs.statSync(cacheFile);
const fileAge = Date.now() - stats.mtime.getTime();
if (fileAge < 86400000) { // 24 heures en millisecondes
console.log(`Utilisation du JWKS mis en cache depuis : ${cacheFile}`);
return fs.readFileSync(cacheFile, 'utf8');
}
}
// Télécharger le JWKS
console.log(`Téléchargement du JWKS depuis : ${jwksUrl}`);
const response = await fetch(jwksUrl);
if (!response.ok) {
throw new Error(`Échec du téléchargement du JWKS : HTTP ${response.status}`);
}
const jwksJson = await response.text();
// Mettre en cache le JWKS
fs.writeFileSync(cacheFile, jwksJson);
console.log(`JWKS mis en cache dans : ${cacheFile}`);
return jwksJson;
}
async function main() {
console.log('=== Validateur JWT Node.js ===');
console.log(`Jeton : ${SAMPLE_JWT_TOKEN.substring(0, 50)}...`);
console.log(`URL JWKS : ${JWKS_URL}`);
console.log('');
try {
// Télécharger et mettre en cache le JWKS
const jwksJson = await downloadAndCacheJWKS(JWKS_URL, JWKS_CACHE_FILE);
console.log("JWKS téléchargé et mis en cache avec succès");
// Analyser le JWKS et extraire les coordonnées de la clé
const jwks = JSON.parse(jwksJson);
if (!jwks.keys || jwks.keys.length === 0) {
throw new Error("Aucune clé trouvée dans le JWKS");
}
const key = jwks.keys[0];
// Valider en utilisant la bibliothèque jose (recommandée)
console.log('Utilisation de la bibliothèque jose :');
const resultJose = await validateReferralTokenJose(SAMPLE_JWT_TOKEN, jwksJson);
if (resultJose.isValid) {
console.log('✅ Validation du jeton réussie !');
console.log(`ID de campagne : ${resultJose.campaignID}`);
console.log(`ID de création : ${resultJose.creativeID}`);
console.log(`RCLID : ${resultJose.rclid}`);
console.log(`Émis à : ${resultJose.issuedAt.toISOString()}`);
``` } else {
console.error(`❌ Échec de la validation du jeton : ${resultJose.error}`);
}
console.log('');
// Montrer une méthode alternative
console.log('Méthode alternative utilisant jsonwebtoken :');
console.log('Remarque : Nécessite une conversion JWK en PEM appropriée');
const resultJWT = validateReferralTokenJWT(SAMPLE_JWT_TOKEN, jwksJson);
console.log(`Résultat : ${resultJWT.isValid ? 'Valide' : 'Invalide'}`);
} catch (error) {
console.error(`❌ Erreur : ${error.message}`);
}
}
// Exporter les fonctions pour une utilisation dans d'autres modules
module.exports = {
validateReferralTokenJose,
validateReferralTokenJWT
};
// Exécuter l'exemple si ce fichier est exécuté directement
if (require.main === module) {
main().catch(console.error);
}
Exemple d'Entrée/Sortie
Entrée
- Jeton JWT : Copiez le jeton de test depuis la page d'aperçu
- Source de la clé publique :
https://public-api.rokt.com/.well-known/jwks.json
Sortie
=== Validateur JWT Node.js ===
Token : eyJhbGciOiJFUzI1NiIsImtpZCI6InJva3Qtc2lnbmluZy1rZXkiLCJ0eXAiOiJKV1QifQ...
URL JWKS : https://public-api.rokt.com/.well-known/jwks.json
Téléchargement de JWKS depuis : https://public-api.rokt.com/.well-known/jwks.json
JWKS mis en cache dans : jwks_cache.json
JWKS téléchargé et mis en cache avec succès
Utilisation de la bibliothèque jose :
✅ Validation du token réussie !
ID de la campagne : 3436085368692408324
ID de la création : 3437732754935906308
RCLID : 7db958dbd232247a4a8285a34d22fe0f4e9affa463bf5ee54e26721ab0df0e23
Émis à : 2025-08-20T05:10:01.000Z
Méthode alternative utilisant jsonwebtoken :
Note : Nécessite une conversion correcte de JWK à PEM
Résultat : Invalide
Comment exécuter
- Enregistrez le code dans
rokt_jwt_validator.js - Installez les dépendances :
npm install jose jsonwebtoken - Exécutez :
node rokt_jwt_validator.js
Implémentation alternative avec les modules ES
Si vous préférez les modules ES, vous pouvez utiliser cette syntaxe :
import { jwtVerify, importJWK } from 'jose';
// ... le reste du code reste le même
Notes
-
La bibliothèque
joseest recommandée pour les applications Node.js modernes -
La clé publique est récupérée à partir de l'endpoint JWKS de Rokt
-
L'exemple utilise l'algorithme ECDSA-256 (ES256) pour la vérification de signature
-
Envisagez de mettre en cache la clé publique pour améliorer les performances
-
La bibliothèque
josegère automatiquement la conversion de JWK en clé publique