验证请求中的简单令牌 - Amazon CloudFront
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

验证请求中的简单令牌

以下函数示例将验证请求的查询字符串中的 JSON Web 令牌 (JWT)。如果令牌有效,则该函数将原始的、未经修改的请求返回到。 CloudFront如果令牌无效,该函数将生成错误响应。此函数使用 crypto 模块。有关更多信息,请参阅内置模块

此函数假定请求在名为 jwt 的查询字符串参数中包含 JWT 值。

警告

要使用此函数,您必须将密钥放在函数代码中。

这是查看器请求函数。

请看上面的这个例子 GitHub

JavaScript runtime 2.0
const crypto = require('crypto'); //Response when JWT is not valid. const response401 = { statusCode: 401, statusDescription: 'Unauthorized' }; 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 header = JSON.parse(_base64urlDecode(headerSeg)); 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; } var xor = 0; for (var 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') } function handler(event) { const 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; } const 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; }
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; }