Valider un jeton simple dans la requête - Amazon CloudFront

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Valider un jeton simple dans la requête

La fonction de demande d'affichage suivante valide un jeton JSON Web (JWT) dans la chaîne de requête d'une demande. Si le jeton est valide, la fonction renvoie la demande originale non modifiée à CloudFront. Si le jeton n'est pas valide, la fonction génère une réponse d'erreur. Cette fonction utilise le module crypto. Pour de plus amples informations, veuillez consulter Modules intégrés.

Cette fonction suppose que les demandes contiennent une JWT valeur dans un paramètre de chaîne de requête nomméjwt. L' CloudFront KeyValueStore identifiant est facultatif dans le code suivant.

Consultez cet exemple sur 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' }; // Remember to associate the KVS with your function before calling the const kvsKey = 'jwt.secret'. // https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/kvs-with-functions-associate.html 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(); 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); } }