Validate a simple token in the request - Amazon CloudFront

Validate a simple token in the request

The following example function validates a JSON web token (JWT) in the query string of a request. If the token is valid, the function returns the original, unmodified request to CloudFront. If the token is not valid, the function generates an error response. This function uses the crypto module. For more information, see Built-in modules.

This function assumes that requests contain a JWT value in a query string parameter named jwt. Also, for this function to work, you must configure CloudFront to cache based on the jwt query string parameter. For more information, see Controlling the cache key.

Warning

To use this function, you must put your secret key in the function code.

This is a viewer request function.

See this example on GitHub.

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