【问题标题】:CDK: How to get apigateway key value (ie x-api-key: *20 Chars*)CDK: How to get apigateway key value (即 x-api-key: *20 Chars*)
【发布时间】:2021-02-10 18:05:11
【问题描述】:

我不知道如何从 apigateway 密钥中获取 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
      });

【问题讨论】:

    标签: amazon-web-services aws-api-gateway aws-cdk amazon-api-gateway


    【解决方案1】:

    如果没有自定义资源,我们无法通过 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(),
    });
    

    【讨论】:

    • 当我尝试这个时,new CfnOutput(this, 'apiKey', { value: apiKeyValue }); 我在输出中得到{{resolve:secretsmanager:arn:aws:secretsmanager:ACCOUNT_REGION:ACCOUNT_ID:secret:SecretA720EF05-H00fwZaCDdXl-7qCK6U:SecretString:apiKey::}} 而不是实际的密钥。我已经替换了帐户区域和 ID,但你明白了。
    【解决方案2】:

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

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

    【讨论】:

    • 这样做可能会在每次部署时更改 API 密钥。我不完全确定 SDK 的 getRandomPassword,但我尝试了与 Node 的加密模块类似的东西,它有这种“副作用”
    【解决方案3】:

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

    这是一个 sn-p,它将为您获取 api 密钥的值。这个key的值是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");
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-26
      • 1970-01-01
      • 2018-10-10
      • 2022-12-01
      • 2022-12-27
      • 2022-12-01
      • 2022-12-27
      • 2013-03-23
      • 2022-12-27
      相关资源
      最近更新 更多