CDK:如何获取api网关密钥值(即x-api-key: *20 Chars*)

CDK: How to get apigateway key value (ie x-api-key: *20 Chars*)

我无法找到如何从 api 网关密钥中获取 api 密钥。我可以得到它的 ID 和它的 ARN,但不能得到它的值。我知道您可以在创建密钥时指定值,但不能指定创建后如何检索它——缺少登录 AWS GUI 并以这种方式找到它。

我查看了 aws-apigateway.ApiKey 的文档,但找不到任何方法来获取该值。 https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.ApiKey.html 我也查看了 kms 密钥,因为您可以获得它们的值,但我不知道它是否可用于 API 网关使用计划(未包含在下面的代码中)。

无法获取值,有没有办法生成一个不会改变或持续存在的值?我正在使用临时 Jenkins 节点 运行 CDK。

    const apiGateway  = require('@aws-cdk/aws-apigateway');
...
    const apiKey = new apiGateway.ApiKey(this, 'api-key', {
      apiKeyName: 'my-api-key',
    });
...
    new cdk.CfnOutput(this, 'x-api-key-apiKey_id', {
      value: apiKey.keyId
      });
    new cdk.CfnOutput(this, 'x-api-key-apiKey_keyArn', {
      value: apiKey.keyArn
      });

如果没有自定义资源,我们无法通过 cdk/cloudformation 检索自动生成的密钥。但我们可以生成密钥,将其存储在秘密管理器或 ssm 秘密中,并使用它来创建 api 密钥。

const secret = new secretsmanager.Secret(this, 'Secret', {
    generateSecretString: {
        generateStringKey: 'api_key',
        secretStringTemplate: JSON.stringify({ username: 'web_user' }),
        excludeCharacters: ' %+~`#$&*()|[]{}:;<>?!\'/@"\',
    },
});
this.restApi.addApiKey('ApiKey', {
    apiKeyName: `web-app-key`,
    value: secret.secretValueFromJson('api_key').toString(),
});

我将使用 https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#getRandomPassword-property 生成 20 个字符并设置 API 键。由于我的堆栈之外没有任何东西需要密钥,所以我可以在每次部署时重新生成它并更新我的资源。但是,如果堆栈之外的东西需要密钥,那么使用 Balu 的答案是最好的选择。

这样做的原因是保守秘密需要付出代价。

公认的答案可能不是解决此问题的最佳方法。 无需使用 aws-cdk 的自定义资源创建额外的秘密即可解决此问题。

这是一个片段,可以让您获得 api 键的值。此密钥的值由 api 网关随机生成。

import * as iam from "@aws-cdk/aws-iam";
import { RetentionDays } from "@aws-cdk/aws-logs";
import * as cdk from "@aws-cdk/core";
import {
  AwsCustomResource,
  AwsCustomResourcePolicy,
  AwsSdkCall,
  PhysicalResourceId,
} from "@aws-cdk/custom-resources";
import { IApiKey } from "@aws-cdk/aws-apigateway";

export interface GetApiKeyCrProps {
  apiKey: IApiKey;
}

export class GetApiKeyCr extends cdk.Construct {
  apikeyValue: string;

  constructor(scope: cdk.Construct, id: string, props: GetApiKeyCrProps) {
    super(scope, id);

    const apiKey: AwsSdkCall = {
      service: "APIGateway",
      action: "getApiKey",
      parameters: {
        apiKey: props.apiKey.keyId,
        includeValue: true,
      },
      physicalResourceId: PhysicalResourceId.of(`APIKey:${props.apiKey.keyId}`),
    };

    const apiKeyCr = new AwsCustomResource(this, "api-key-cr", {
      policy: AwsCustomResourcePolicy.fromStatements([
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          resources: [props.apiKey.keyArn],
          actions: ["apigateway:GET"],
        }),
      ]),
      logRetention: RetentionDays.ONE_DAY,
      onCreate: apiKey,
      onUpdate: apiKey,
    });

    apiKeyCr.node.addDependency(props.apiKey);
    this.apikeyValue = apiKeyCr.getResponseField("value");
  }
}