You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:35:20