メインコンテンツまでスキップ

Node.js JWT Validation Example

⚠️ 重要なお知らせ: これはデモンストレーション目的の基本的な例です。実際の運用では、ソフトウェアスタック、セキュリティ要件、デプロイ環境に特化したベストプラクティスを調査し、実装してください。常に組織のセキュリティガイドラインに従い、確立されたJWTライブラリやフレームワークの使用を検討してください。

📝 注記: この例は教育目的でJWKSのダウンロードとファイルキャッシングを示しています。運用環境では、インフラストラクチャに基づいてJWKSキー管理を異なる方法で実装することを選択するかもしれません - 例えば、構成管理、環境変数、または好みのキャッシング戦略を使用するなど。

この例は、Node.jsを使用してRokt JWTトークンを検証する方法を示しています。

前提条件前提条件 への直接リンク

必要なパッケージをインストールします:

npm install jose jsonwebtoken

完全な例完全な例 への直接リンク

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

入出力例入出力例 への直接リンク

入力入力 への直接リンク

  • JWTトークン: 概要ページからテストトークンをコピー
  • 公開鍵ソース: https://public-api.rokt.com/.well-known/jwks.json

出力出力 への直接リンク

=== 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

実行方法実行方法 への直接リンク

  1. コードをrokt_jwt_validator.jsに保存
  2. 依存関係をインストール: npm install jose jsonwebtoken
  3. 実行: node rokt_jwt_validator.js

ESモジュールを使用した代替実装ESモジュールを使用した代替実装 への直接リンク

ESモジュールを好む場合は、この構文を使用できます:

import { jwtVerify, importJWK } from 'jose';

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

注記注記 への直接リンク

  • joseライブラリは、最新のNode.jsアプリケーションに推奨されます

  • 公開鍵はRoktのJWKSエンドポイントから取得されます

  • この例では、署名検証にECDSA-256 (ES256)アルゴリズムを使用しています

  • パフォーマンスのために公開鍵をキャッシュすることを検討してください

  • joseライブラリは、JWKから公開鍵への変換を自動的に処理します

この記事は役に立ちましたか?