Cloudwatch Synthetics Canary多步骤API检查:传递认证Token至后续请求
解决CloudWatch Synthetics Canary跨步骤Token传递问题
需求是搭建CloudWatch Synthetics Canary,先通过POST请求调用认证API获取Token,再将该Token用于第二个请求的请求头中。原代码已完成两步请求,但未实现Token的提取和传递,以下是修改后的完整代码及关键说明:
原问题背景
原第一步请求响应体格式:
{"access_token": "MYTOKEN", "scope": "vds rc", "expires_in": 51719, "token_type": "Bearer"}
需要提取access_token值,替换第二步请求头中VALUE FROM FIRST REQEST的位置。
修改后的完整代码
const synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const syntheticsConfiguration = synthetics.getConfiguration(); const apiCanaryBlueprint = async function () { const [ key, cert ] = await getKeyCert(); syntheticsConfiguration.setConfig({ restrictedHeaders: [], // 这些头的值会从日志和报告中脱敏 restrictedUrlParameters: [] // 这些URL参数的值会从日志和报告中脱敏 }); // 处理成功场景的验证,同时返回解析后的access_token const validateSuccessfulAndExtractToken = async function(res) { return new Promise((resolve, reject) => { if (res.statusCode < 200 || res.statusCode > 299) { throw new Error(res.statusCode + ' ' + res.statusMessage); } let responseBody = ''; res.on('data', (d) => { responseBody += d; }); res.on('end', () => { try { // 解析响应体为JSON const tokenData = JSON.parse(responseBody); // 提取access_token并返回 resolve(tokenData.access_token); } catch (parseError) { reject(new Error('Failed to parse token response: ' + parseError.message)); } }); }); }; // 第一步:获取认证Token let requestOptionsStep1 = { hostname: 'mywebsite.com', method: 'POST', path: '/v1/oauth/token', port: '443', protocol: 'https:', body: JSON.stringify({ "client_id": "xxx", "client_secret": "yyy", "audience": "https://mywebsite.com", "grant_type": "client_credentials" }), headers: {"Content-Type": "application/json"}, key: key, cert: cert }; requestOptionsStep1['headers']['User-Agent'] = [synthetics.getCanaryUserAgentString(), requestOptionsStep1['headers']['User-Agent']].join(' '); let stepConfig1 = { includeRequestHeaders: true, includeResponseHeaders: true, includeRequestBody: true, includeResponseBody: true, continueOnHttpStepFailure: true }; // 执行第一步请求并获取返回的access_token const accessToken = await synthetics.executeHttpStep('获取认证Token', requestOptionsStep1, validateSuccessfulAndExtractToken, stepConfig1); log.info('Successfully retrieved access token'); // 第二步:使用Token调用目标API let requestOptionsStep2 = { hostname: 'mywebsite.com', method: 'GET', path: '/my/api/request/path', port: '443', protocol: 'https:', body: "", headers: { "content-type": "application/json", // 修正authorization键的拼写错误,并填入获取到的Token "authorization": `Bearer ${accessToken}` } }; requestOptionsStep2['headers']['User-Agent'] = [synthetics.getCanaryUserAgentString(), requestOptionsStep2['headers']['User-Agent']].join(' '); let stepConfig2 = { includeRequestHeaders: true, includeResponseHeaders: true, includeRequestBody: true, includeResponseBody: true, continueOnHttpStepFailure: true }; await synthetics.executeHttpStep('调用目标API', requestOptionsStep2, validateSuccessfulAndExtractToken, stepConfig2); }; exports.handler = async () => { return await apiCanaryBlueprint(); };
关键改动说明
- 修改验证函数:将原
validateSuccessful改为validateSuccessfulAndExtractToken,在响应结束时解析JSON响应体,提取access_token并通过resolve返回,同时增加了解析失败的错误处理。 - 获取Token并存储:执行第一步请求时,接收
executeHttpStep返回的accessToken变量,用于后续请求。 - 修正请求头并填入Token:修正第二步请求头中
authorization:的拼写错误(去掉多余的冒号),并使用模板字符串将Token格式化为Bearer ${accessToken}的标准认证头格式。 - 优化请求体写法:第一步的请求体改用
JSON.stringify生成,避免手动拼接字符串时的转义错误。
内容的提问来源于stack exchange,提问作者Martin W
相关产品推荐
相关产品推荐

