Aller au contenu principal

Exemple de Validation JWT Node.js

⚠️ Avis Important : Ceci est un exemple de base à 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 mettre en œuvre la gestion des clés JWKS différemment en fonction de votre infrastructure - comme en utilisant la gestion de configuration, des 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érequisLien direct vers Prérequis

Installez les paquets requis :

npm install jose jsonwebtoken

Exemple CompletLien direct vers Exemple Complet

const { jwtVerify, importJWK } = require('jose');
const jwt = require('jsonwebtoken');

// Sample JWT token from Rokt
// Copy the test token from the Overview page
const SAMPLE_JWT_TOKEN = "PASTE_TEST_TOKEN_HERE";

// JWKS endpoint URL
const JWKS_URL = "https://public-api.rokt.com/.well-known/jwks.json";
const JWKS_CACHE_FILE = "jwks_cache.json";

/**
* Validate JWT token using jose library (recommended)
*/
async function validateReferralTokenJose(jwtToken, jwksJson) {
try {
// Parse JWKS
const jwks = typeof jwksJson === 'string' ? JSON.parse(jwksJson) : jwksJson;

if (!jwks.keys || jwks.keys.length === 0) {
throw new Error('No keys found in JWKS');
}

// Get the first key
const jwk = jwks.keys[0];

// Import JWK to create public key
const publicKey = await importJWK(jwk, 'ES256');

// Verify and decode JWT token
const { payload } = await jwtVerify(jwtToken, publicKey, {
algorithms: ['ES256'],
clockTolerance: '1m' // Allow 1 minute clock skew
});

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
};
}
}

/**
* Alternative implementation using jsonwebtoken library
*/
function validateReferralTokenJWT(jwtToken, jwksJson) {
try {
// Parse JWKS
const jwks = typeof jwksJson === 'string' ? JSON.parse(jwksJson) : jwksJson;

if (!jwks.keys || jwks.keys.length === 0) {
throw new Error('No keys found in JWKS');
}

// Get the first key
const jwk = jwks.keys[0];

// For jsonwebtoken, you would need to convert JWK to PEM format
// This is a simplified example - in practice, you'd need proper JWK to PEM conversion
const publicKeyPem = `-----BEGIN PUBLIC KEY-----
YOUR_PUBLIC_KEY_PEM_HERE
-----END PUBLIC KEY-----`;

// Verify and decode JWT token
const decoded = jwt.verify(jwtToken, publicKeyPem, {
algorithms: ['ES256'],
clockTolerance: 60 // Allow 1 minute clock skew
});

return {
isValid: true,
campaignID: decoded.cid,
creativeID: decoded.crid,
rclid: decoded.rclid,
issuedAt: new Date(decoded.iat * 1000)
};
} catch (error) {
return {
isValid: false,
error: error.message
};
}
}

/**
* Main function to demonstrate token validation
*/
async function downloadAndCacheJWKS(jwksUrl, cacheFile) {
const fs = require('fs');
const path = require('path');

// Check if cache file exists and is recent (less than 24 hours old)
if (fs.existsSync(cacheFile)) {
const stats = fs.statSync(cacheFile);
const fileAge = Date.now() - stats.mtime.getTime();
if (fileAge < 86400000) { // 24 hours in milliseconds
console.log(`Using cached JWKS from: ${cacheFile}`);
return fs.readFileSync(cacheFile, 'utf8');
}
}

// Download JWKS
console.log(`Downloading JWKS from: ${jwksUrl}`);
const response = await fetch(jwksUrl);
if (!response.ok) {
throw new Error(`Failed to download JWKS: HTTP ${response.status}`);
}

const jwksJson = await response.text();

// Cache the JWKS
fs.writeFileSync(cacheFile, jwksJson);
console.log(`JWKS cached to: ${cacheFile}`);

return jwksJson;
}

async function main() {
console.log('=== Node.js JWT Validator ===');
console.log(`Token: ${SAMPLE_JWT_TOKEN.substring(0, 50)}...`);
console.log(`JWKS URL: ${JWKS_URL}`);
console.log('');

try {
// Download and cache JWKS
const jwksJson = await downloadAndCacheJWKS(JWKS_URL, JWKS_CACHE_FILE);
console.log("JWKS downloaded and cached successfully");

// Parse JWKS and extract key coordinates
const jwks = JSON.parse(jwksJson);
if (!jwks.keys || jwks.keys.length === 0) {
throw new Error("No keys found in JWKS");
}

const key = jwks.keys[0];

// Validate using jose library (recommended)
console.log('Using jose library:');
const resultJose = await validateReferralTokenJose(SAMPLE_JWT_TOKEN, jwksJson);

if (resultJose.isValid) {
console.log('✅ Token validation successful!');
console.log(`Campaign ID: ${resultJose.campaignID}`);
console.log(`Creative ID: ${resultJose.creativeID}`);
console.log(`RCLID: ${resultJose.rclid}`);
console.log(`Issued At: ${resultJose.issuedAt.toISOString()}`);
} else {
console.error(`❌ Token validation failed: ${resultJose.error}`);
}

console.log('');

// Show alternative method
console.log('Alternative method using jsonwebtoken:');
console.log('Note: Requires proper JWK to PEM conversion');
const resultJWT = validateReferralTokenJWT(SAMPLE_JWT_TOKEN, jwksJson);
console.log(`Result: ${resultJWT.isValid ? 'Valid' : 'Invalid'}`);
} catch (error) {
console.error(`❌ Error: ${error.message}`);
}
}

// Export functions for use in other modules
module.exports = {
validateReferralTokenJose,
validateReferralTokenJWT
};

// Run example if this file is executed directly
if (require.main === module) {
main().catch(console.error);
}

Exemple d'Entrée/SortieLien direct vers Exemple d'Entrée/Sortie

EntréeLien direct vers 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

SortieLien direct vers Sortie

=== Node.js JWT Validator ===
Token: eyJhbGciOiJFUzI1NiIsImtpZCI6InJva3Qtc2lnbmluZy1rZXkiLCJ0eXAiOiJKV1QifQ...
JWKS URL: https://public-api.rokt.com/.well-known/jwks.json

Downloading JWKS from: https://public-api.rokt.com/.well-known/jwks.json
JWKS cached to: jwks_cache.json
JWKS downloaded and cached successfully

Using jose library:
✅ Token validation successful!
Campaign ID: 3436085368692408324
Creative ID: 3437732754935906308
RCLID: 7db958dbd232247a4a8285a34d22fe0f4e9affa463bf5ee54e26721ab0df0e23
Issued At: 2025-08-20T05:10:01.000Z

Alternative method using jsonwebtoken:
Note: Requires proper JWK to PEM conversion
Result: Invalid

Comment ExécuterLien direct vers Comment Exécuter

  1. Enregistrez le code dans rokt_jwt_validator.js
  2. Installez les dépendances : npm install jose jsonwebtoken
  3. Exécutez : node rokt_jwt_validator.js

Implémentation Alternative avec Modules ESLien direct vers Implémentation Alternative avec Modules ES

Si vous préférez les modules ES, vous pouvez utiliser cette syntaxe :

import { jwtVerify, importJWK } from 'jose';

// ... rest of the code remains the same

RemarquesLien direct vers Remarques

  • La bibliothèque jose est recommandée pour les applications Node.js modernes

  • La clé publique est récupérée depuis le point d'accès 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 les performances

  • La bibliothèque jose gère automatiquement la conversion de JWK en clé publique

Cet article vous a-t-il été utile ?