Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Convalida di un token semplice nella richiesta
La seguente funzione di richiesta del visualizzatore convalida un token web JSON (JWT)crypto
. Per ulteriori informazioni, consulta Moduli incorporati.
Questa funzione presuppone che le richieste contengano un valore JWT in un parametro stringa di query denominato jwt
.
Nota
Per utilizzare questa funzione, devi inserire il tuo CloudFront KeyValueStore ID Amazon nel codice della funzione.
Guarda questo esempio su GitHub
- JavaScript runtime 2.0
-
import crypto from 'crypto'; import cf from 'cloudfront'; //Response when JWT is not valid. const response401 = { statusCode: 401, statusDescription: 'Unauthorized' }; // Replace the KVS_ID with your KVS ID const kvsId = "KVS_ID"; const kvsKey = 'jwt.secret'; // set to true to enable console logging const loggingEnabled = false; function jwt_decode(token, key, noVerify, algorithm) { // check token if (!token) { throw new Error('No token supplied'); } // check segments const segments = token.split('.'); if (segments.length !== 3) { throw new Error('Not enough or too many segments'); } // All segment should be base64 const headerSeg = segments[0]; const payloadSeg = segments[1]; const signatureSeg = segments[2]; // base64 decode and parse JSON const payload = JSON.parse(_base64urlDecode(payloadSeg)); if (!noVerify) { const signingMethod = 'sha256'; const signingType = 'hmac'; // Verify signature. `sign` will return base64 string. const signingInput = [headerSeg, payloadSeg].join('.'); if (!_verify(signingInput, key, signingMethod, signingType, signatureSeg)) { throw new Error('Signature verification failed'); } // Support for nbf and exp claims. // According to the RFC, they should be in seconds. if (payload.nbf && Date.now() < payload.nbf*1000) { throw new Error('Token not yet active'); } if (payload.exp && Date.now() > payload.exp*1000) { throw new Error('Token expired'); } } return payload; } //Function to ensure a constant time comparison to prevent //timing side channels. function _constantTimeEquals(a, b) { if (a.length != b.length) { return false; } let xor = 0; for (let i = 0; i < a.length; i++) { xor |= (a.charCodeAt(i) ^ b.charCodeAt(i)); } return 0 === xor; } function _verify(input, key, method, type, signature) { if(type === "hmac") { return _constantTimeEquals(signature, _sign(input, key, method)); } else { throw new Error('Algorithm type not recognized'); } } function _sign(input, key, method) { return crypto.createHmac(method, key).update(input).digest('base64url'); } function _base64urlDecode(str) { return Buffer.from(str, 'base64url') } async function handler(event) { let request = event.request; //Secret key used to verify JWT token. //Update with your own key. const secret_key = await getSecret() if(!secret_key) { return response401; } // If no JWT token, then generate HTTP redirect 401 response. if(!request.querystring.jwt) { log("Error: No JWT in the querystring"); return response401; } const jwtToken = request.querystring.jwt.value; try{ jwt_decode(jwtToken, secret_key); } catch(e) { log(e); return response401; } //Remove the JWT from the query string if valid and return. delete request.querystring.jwt; log("Valid JWT token"); return request; } // get secret from key value store async function getSecret() { // initialize cloudfront kv store and get the key value try { const kvsHandle = cf.kvs(kvsId); return await kvsHandle.get(kvsKey); } catch (err) { log(`Error reading value for key: ${kvsKey}, error: ${err}`); return null; } } function log(message) { if (loggingEnabled) { console.log(message); } }
- JavaScript runtime 1.0
-
var crypto = require('crypto'); //Response when JWT is not valid. var response401 = { statusCode: 401, statusDescription: 'Unauthorized' }; function jwt_decode(token, key, noVerify, algorithm) { // check token if (!token) { throw new Error('No token supplied'); } // check segments var segments = token.split('.'); if (segments.length !== 3) { throw new Error('Not enough or too many segments'); } // All segment should be base64 var headerSeg = segments[0]; var payloadSeg = segments[1]; var signatureSeg = segments[2]; // base64 decode and parse JSON var header = JSON.parse(_base64urlDecode(headerSeg)); var payload = JSON.parse(_base64urlDecode(payloadSeg)); if (!noVerify) { var signingMethod = 'sha256'; var signingType = 'hmac'; // Verify signature. `sign` will return base64 string. var signingInput = [headerSeg, payloadSeg].join('.'); if (!_verify(signingInput, key, signingMethod, signingType, signatureSeg)) { throw new Error('Signature verification failed'); } // Support for nbf and exp claims. // According to the RFC, they should be in seconds. if (payload.nbf && Date.now() < payload.nbf*1000) { throw new Error('Token not yet active'); } if (payload.exp && Date.now() > payload.exp*1000) { throw new Error('Token expired'); } } return payload; } function _verify(input, key, method, type, signature) { if(type === "hmac") { return (signature === _sign(input, key, method)); } else { throw new Error('Algorithm type not recognized'); } } function _sign(input, key, method) { return crypto.createHmac(method, key).update(input).digest('base64url'); } function _base64urlDecode(str) { return String.bytesFrom(str, 'base64url') } function handler(event) { var request = event.request; //Secret key used to verify JWT token. //Update with your own key. var key = "LzdWGpAToQ1DqYuzHxE6YOqi7G3X2yvNBot9mCXfx5k"; // If no JWT token, then generate HTTP redirect 401 response. if(!request.querystring.jwt) { console.log("Error: No JWT in the querystring"); return response401; } var jwtToken = request.querystring.jwt.value; try{ jwt_decode(jwtToken, key); } catch(e) { console.log(e); return response401; } //Remove the JWT from the query string if valid and return. delete request.querystring.jwt; console.log("Valid JWT token"); return request; }