我无法找到如何从 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
});
如果没有自定义资源,我们无法通过 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(),
});
接受的答案可能不是解决这个问题的最佳方法。 无需使用 aws-cdk 的自定义资源创建额外的密钥即可解决此问题。
这里有一个片段,可以让您获取 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");
}
}
我将使用 https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#getRandomPassword-property 生成 20 个字符并设置 API 密钥。由于我的堆栈之外没有任何东西需要密钥,所以我可以在每次部署时重新生成它并更新我的资源。但是,如果堆栈之外的东西需要密钥,那么使用 Balu 的答案是最好的选择。
这样做的原因是保守秘密是有相关成本的。
@ishan-jain 解决方案的 Python 版本:
class GetApiKeyCr(Construct):
def __init__(self, scope: Stack, id: str, api_key: aws_apigateway.IApiKey):
self.apikey_value: str
super().__init__(scope, id)
api_key_details: custom_resources.AwsSdkCall = custom_resources.AwsSdkCall(
service="APIGateway",
action="getApiKey",
parameters={
"apiKey": api_key.key_id,
"includeValue": True,
},
physical_resource_id=custom_resources.PhysicalResourceId.of(
f"APIKey:{api_key.key_id}"
),
)
api_key_cr = custom_resources.AwsCustomResource(
self,
"api-key-cr",
policy=custom_resources.AwsCustomResourcePolicy.from_statements(
[
aws_iam.PolicyStatement(
effect=aws_iam.Effect.ALLOW,
resources=[api_key.key_arn],
actions=["apigateway:GET"],
),
]
),
log_retention=aws_logs.RetentionDays.ONE_DAY,
on_create=api_key_details,
on_update=api_key_details,
)
api_key_cr.node.add_dependency(api_key)
self.apikey_value = api_key_cr.get_response_field("value")