

# API Gateway 中针对 REST API 的使用计划和 API 密钥
<a name="api-gateway-api-usage-plans"></a>

创建、测试和部署 API 后，您可以实施 API Gateway 使用计划，将它们作为面向客户的产品/服务提供。您可以配置使用计划和 API 密钥，以允许客户访问选定的 API，并根据定义的限制和配额开始对这些API的请求进行节流。这些可以在 API 或 API 方法级别设置。

## 什么是使用计划和 API 密钥？
<a name="api-gateway-api-usage-plans-overview"></a>

一个*使用计划*指定谁可以访问一个或多个部署的 API 阶段和方法 — 可以选择设置目标请求速率来启动限制请求。该计划使用 API 密钥来标识 API 客户端，以及针对每个密钥对关联的 API 阶段的访问人员。

*API 密钥* 是字母数字字符串值，可将它分发给应用程序开发人员（要向其授予对您的 API 的访问权的客户）。您可以将 API 密钥与 [Lambda 授权方](apigateway-use-lambda-authorizer.md)、[IAM 角色](permissions.md)或 [Amazon Cognito](apigateway-integrate-with-cognito.md) 一起使用，以控制对 API 的访问。API Gateway 可以代表您生成 API 密钥，也可以从 [CSV 文件](api-key-file-format.md)中导入 API 密钥。您可以在 API Gateway 中生成 API 密钥，或从外部源将其导入 API Gateway。有关更多信息，请参阅 [在 API Gateway 中为 REST API 设置 API 密钥](api-gateway-setup-api-keys.md)。

API 密钥具有一个名称和值。（术语“API 密钥”和“API 密钥值”经常互换使用。） 名称不能超过 1024 个字符。值为一个长度在 20 到 128 个字符之间的字母数字字符串，例如，`apikey1234abcdefghij0123456789`。

**重要**  
API 密钥值必须是唯一的。如果您尝试使用不同的名称和相同的值来创建两个 API 密钥，API Gateway 会将它们视为同一 API 密钥。  
一个 API 密钥可与多个使用计划关联。一个使用计划可与多个阶段关联。但是，对于 API 的每个阶段，给定 API 密钥只能与一个使用计划关联。

一个*限制*设置请求限制应该开始的目标点。这可以在 API 或 API 方法级别设置。

*配额限制*可设置在指定的时间间隔内提交的包含给定 API 密钥的最大目标请求数。您可以配置单独的 API 方法，要求根据使用计划配置进行 API 密钥授权。

限制和配额限制适用于跨一个使用计划内的所有 API 阶段聚合的各个 API 密钥的请求。

**注意**  
使用计划节流和配额不是硬性限制，而是在尽力而为的基础上应用的。在某些情况下，客户端可能会超过您设置的配额。不要依靠使用计划配额或节流来控制成本或阻止对 API 的访问。考虑使用 [AWS Budgets](https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-managing-costs.html) 监控成本和 [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) 来管理 API 请求。

## API 密钥和使用计划的最佳实践
<a name="apigateway-usage-plans-best-practices"></a>

以下是使用 API 密钥和使用计划时要遵循的建议的最佳实践。

**重要**  
请勿使用 API 密钥进行身份验证或授权以控制对 API 的访问权限。如果您在一个使用计划中有多个 API，则具有该使用计划中的一个 API 的有效 API 密钥的用户可以访问该使用计划中的*所有* API。相反，要控制对 API 的访问权限，请使用 IAM 角色、[Lambda 授权方](apigateway-use-lambda-authorizer.md)或 [Amazon Cognito 用户群体](apigateway-integrate-with-cognito.md)。
使用 API Gateway 生成的 API 密钥。API 密钥不应包含机密信息；客户端通常使用可记录的标头传输这些信息。
+ 如果您使用开发人员门户发布 API，请注意，给定使用计划中的所有 API 均可由客户订阅，即使您尚未向您的客户显示它们。
+ 在某些情况下，客户端可能会超过您设置的配额。不要依靠使用计划来控制成本。考虑使用 [AWS Budgets](https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-managing-costs.html) 监控成本和 [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) 来管理 API 请求。
+ 将 API 密钥添加到使用计划后，更新操作可能需要几分钟才能完成。

# 在 API Gateway 中选择一个 API 密钥源
<a name="api-gateway-api-key-source"></a>

在将使用计划与 API 关联并在 API 方法上启用 API 密钥时，针对 API 的传入请求必须包含 [API 密钥](api-gateway-basic-concept.md#apigateway-definition-api-key)。API Gateway 将读取密钥并将它与使用计划中的密钥进行比较。如果匹配，API Gateway 将基于计划的请求限制和配额限制请求。否则，将引发 `InvalidKeyParameter` 异常。作为结果，调用方将收到 `403 Forbidden` 响应。

您的 API Gateway API 可从下面两个源之一接收 API 密钥：

**`HEADER`**  
您将 API 密钥分发给您的客户，并要求其将 API 密钥作为每个传入请求的 `X-API-Key` 标头传递。

**`AUTHORIZER`**  
您可以让 Lambda 授权方将 API 密钥作为授权响应的一部分返回。有关授权响应的更多信息，请参阅[来自 API Gateway Lambda 授权方的输出](api-gateway-lambda-authorizer-output.md)。

**注意**  
有关可考虑的最佳实践，请参阅 [API 密钥和使用计划的最佳实践](api-gateway-api-usage-plans.md#apigateway-usage-plans-best-practices)。

以下过程显示如何为 API 选择 API 密钥源。

------
#### [ AWS 管理控制台 ]

**为 API 选择 API 密钥源**

1. 登录 API Gateway 控制台。

1. 选择现有 API 或者创建新 API。

1. 在主导航窗格中，选择 **API 设置**。

1. 在 **API 详细信息**部分中，选择**编辑**。

1.  在 **API 密钥源**下，从下拉列表中选择 `Header` 或 `Authorizer`。

1. 选择**保存更改**。

------
#### [ AWS CLI ]

使用以下 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令更新 API，将 API 密钥源设置为 `AUTHORIZER`：

```
aws apigateway update-rest-api --rest-api-id 1234123412 --patch-operations op=replace,path=/apiKeySource,value=AUTHORIZER
```

要让客户端提交 API 密钥，请在以上命令中将 `value` 设置为 `HEADER`。

------
#### [ REST API ]

要使用 API Gateway REST API 为 API 选择 API 密钥源，请按以下所示调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateRestApi.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateRestApi.html)：

```
PATCH /restapis/fugvjdxtri/ HTTP/1.1
Content-Type: application/json
Host: apigateway.us-east-1.amazonaws.com
X-Amz-Date: 20160603T205348Z
Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160603/us-east-1/apigateway/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature={sig4_hash}

{
  "patchOperations" : [
    {
        "op" : "replace",
        "path" : "/apiKeySource",
        "value" : "HEADER"
    }
  ]
}
```

要让授权方返回 API 密钥，请在之前的 `value` 输入中将 `AUTHORIZER` 设置为 `patchOperations`。

------

# API Gateway API 密钥文件格式
<a name="api-key-file-format"></a>

API Gateway 可以从逗号分隔值 (CSV) 格式的外部文件导入 API 密钥，然后将导入的密钥与一个或多个使用计划关联。导入的文件必须包含 `Name` 和 `Key` 列。列标头名称不区分大小写，并且这些列可以采用任何顺序，如以下示例所示：

```
Key,name
apikey1234abcdefghij0123456789,MyFirstApiKey
```

`Key` 值必须介于 20 到 128 个字符之间。`Name` 值不能超过 1024 个字符。

API 密钥文件也可以包含 `Description`、`Enabled` 或 `UsagePlanIds` 列，如以下示例所示：

```
Name,key,description,Enabled,usageplanIds
MyFirstApiKey,apikey1234abcdefghij0123456789,An imported key,TRUE,c7y23b
```

当密钥与多个使用计划关联时，`UsagePlanIds` 值是用双引号或单引号引起来的使用计划 ID 的逗号分隔字符串，如以下示例所示：

```
Enabled,Name,key,UsageplanIds
true,MyFirstApiKey,apikey1234abcdefghij0123456789,"c7y23b,glvrsr"
```

允许使用无法识别的列，但会忽略这些列。默认值为空字符串或 `true` 布尔值。

同一个 API 密钥可以多次导入，最新版本将覆盖前一个版本。如果两个 API 密钥具有相同的 `key` 值，则这两个密钥相同。

**注意**  
有关可考虑的最佳实践，请参阅 [API 密钥和使用计划的最佳实践](api-gateway-api-usage-plans.md#apigateway-usage-plans-best-practices)。

# 在 API Gateway 中为 REST API 设置 API 密钥
<a name="api-gateway-setup-api-keys"></a>

要设置 API 键，请执行以下操作：
+ 将 API 方法配置为需要 API 键。
+ 为区域中的 API 创建或导入 API 密钥。

在设置 API 键之前，您必须先创建一个 API 并将其部署到某个阶段。创建 API 密钥值后，无法更改此值。

有关如何使用 API Gateway 控制台创建和部署 API 的说明，请分别参阅[开发 API Gateway 中的 REST API](rest-api-develop.md)和[在 API Gateway 中部署 REST API。](how-to-deploy-api.md)。

创建 API 密钥后，必须将其与使用计划相关联。有关更多信息，请参阅 [在 API Gateway 中为 REST API 设置使用计划](api-gateway-create-usage-plans.md)。

**注意**  
有关可考虑的最佳实践，请参阅 [API 密钥和使用计划的最佳实践](api-gateway-api-usage-plans.md#apigateway-usage-plans-best-practices)。

**Topics**
+ [要求方法使用 API](#api-gateway-usage-plan-configure-apikey-on-method)
+ [创建 API 密钥](#api-gateway-usage-plan-create-apikey)
+ [导入 API 密钥](#api-gateway-usage-pan-import-apikey)

## 要求方法使用 API
<a name="api-gateway-usage-plan-configure-apikey-on-method"></a>

以下过程介绍如何将 API 方法配置为需要 API 密钥。

------
#### [ AWS 管理控制台 ]

**将 API 方法配置为需要 API 密钥**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择一个 REST API。

1. 在 API Gateway 主导航窗格中，选择**资源**。

1. 在**资源**下，创建新方法或选择现有方法。

1. 在**方法请求**选项卡上的**方法请求设置**下，选择**编辑**。  
![\[将 API 密钥添加到方法\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/api-gateway-new-console-add-key-to-method.png)

1. 选择**需要 API 密钥**。

1. 选择**保存**。

1. 部署或重新部署 API 以使该要求生效。

如果**需要 API 密钥**选项设置为 `false` 并且您没有执行上述步骤，则与 API 阶段关联的任何 API 密钥都不会用于该方法。

------
#### [ AWS CLI ]

以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令创建需要 API 密钥的 `PUT` 方法：

```
aws apigateway put-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --authorization-type "NONE" \
    --api-key-required
```

以下 [update-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-method.html) 命令将现有方法更新为需要 API 密钥：

```
aws apigateway update-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --patch-operations op="replace",path="/apiKeyRequired",value="true"
```

------
#### [ REST API ]

要让某个方法使用 API，请执行以下操作之一：
+ 调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_PutMethod.html](https://docs.aws.amazon.com/apigateway/latest/api/API_PutMethod.html) 以创建方法。在请求负载中将 `apiKeyRequired` 设置为 `true`。
+ 调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateMethod.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateMethod.html) 将 `apiKeyRequired` 设置为 `true`。

------

## 创建 API 密钥
<a name="api-gateway-usage-plan-create-apikey"></a>

以下过程说明如何创建 API 密钥。如果您想要导入 API 密钥，请跳过此步骤。

------
#### [ AWS 管理控制台 ]

**创建 API 密钥**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择一个 REST API。

1. 在 API Gateway 主导航窗格中，选择 **API 密钥**。

1. 选择**创建 API 密钥**。  
![\[为使用计划创建 API 密钥\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/api-gateway-new-console-usage-plan-keys-choose-create-api-key-from-actions-menu.png)

1. 对于**名称**，输入名称。

1. （可选）对于**描述**，输入描述。

1. 对于 **API 密钥**，选择**自动生成**可让 API Gateway 生成密钥值，或者选择**自定义**以创建您自己的密钥值。

1. 选择**保存**。

------
#### [ AWS CLI ]

以下 [create-api-key](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-api-key.html) 命令创建 API 密钥：

```
 aws apigateway create-api-key \
    --name 'Dev API key' \
    --description 'API key for Devs' \
    --enabled
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_CreateApiKey.html](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateApiKey.html) 以创建 API 密钥。

------

## 导入 API 密钥
<a name="api-gateway-usage-pan-import-apikey"></a>

以下过程介绍如何导入 API 密钥。如果您已创建 API 密钥，请跳过此步骤。

------
#### [ AWS 管理控制台 ]

**导入 API 密钥**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择一个 REST API。

1. 在主导航窗格中，选择 **API 密钥**。

1. 选择**操作**下拉菜单，然后选择**导入 API 密钥**。

1. 要加载逗号分隔的密钥文件，请选择**选择文件**。您也可以在文本编辑器中输入密钥。有关文件格式的信息，请参阅 [API Gateway API 密钥文件格式](api-key-file-format.md)。

1. 选择**收到警告停止**以在出现错误时停止导入，或选择**忽略警告**以在出现警告时继续导入有效的密钥条目。

1. 选择**导入**以导入您的 API 密钥。

------
#### [ AWS CLI ]

以下 [import-api-keys](https://docs.aws.amazon.com/cli/latest/reference/apigateway/import-api-keys.html) 命令导入 API 密钥：

```
aws apigateway import-api-key \
    a--body fileb://keys.csv \
    --format csv
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_ImportApiKeys.html](https://docs.aws.amazon.com/apigateway/latest/api/API_ImportApiKeys.html) 以从某个文件导入 API 密钥。有关文件格式的信息，请参阅 [API Gateway API 密钥文件格式](api-key-file-format.md)。

------

您无法更改新 API 密钥的值。创建 API 后，您将配置使用计划。有关更多信息，请参阅 [在 API Gateway 中为 REST API 设置使用计划](api-gateway-create-usage-plans.md)。

# 在 API Gateway 中为 REST API 设置使用计划
<a name="api-gateway-create-usage-plans"></a>

在创建使用计划之前，请确保您已设置 API 密钥。有关更多信息，请参阅 [在 API Gateway 中为 REST API 设置 API 密钥](api-gateway-setup-api-keys.md)。

**Topics**
+ [将您的 API 迁移到默认使用计划（如果需要）](#api-gateway-usage-plan-migrate-to-default)
+ [创建使用计划](#api-gateway-usage-plan-create)
+ [将阶段添加到使用计划中](#api-gateway-usage-plan-add-stage)
+ [将 API 密钥添加到使用计划中](#api-gateway-usage-plan-add-key)

## 将您的 API 迁移到默认使用计划（如果需要）
<a name="api-gateway-usage-plan-migrate-to-default"></a>

如果您在 2016 年 8 月 11 日推出使用计划特征*之后* 开始使用 API Gateway，则会自动在所有受支持区域为您启用使用计划。

如果您在此日期之前开始使用 API Gateway，则可能需要迁移到默认使用计划。在选定区域中首次使用计划之前，系统将提示您选择**启用使用计划**选项。在您启用此选项后，您将为与现有 API 密钥关联的每个唯一 API 阶段创建默认使用计划。在默认使用计划中，最初不设置限制或配额限制，API 密钥和 API 阶段之间的关联将复制到使用计划中。API 的行为方式将与之前相同。但是，您必须使用 [https://docs.aws.amazon.com/apigateway/latest/api/API_UsagePlan.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UsagePlan.html) `apiStages` 属性（而不是使用 [ApiKey](https://docs.aws.amazon.com/apigateway/latest/api/API_ApiKey.html) `stageKeys` 属性）将指定的 API 阶段值（`apiId` 和 `stage`）与所含的 API 密钥进行关联（通过 [https://docs.aws.amazon.com/apigateway/latest/api/API_UsagePlanKey.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UsagePlanKey.html)）。

要检查您是否已迁移到默认使用计划，请使用 [https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-account.html](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-account.html) CLI 命令。在命令输出中，当启用使用计划时，`features` 列表将包括 `"UsagePlans"` 的条目。

您还可以使用 AWS CLI 将您的 API 迁移到默认使用计划，如下所示：

**使用 AWS CLI 迁移到默认使用计划**

1. 调用此 CLI 命令：[https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-account.html](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-account.html)

1. 对于 `cli-input-json` 参数，使用以下 JSON：

   ```
   [
       {
           "op": "add",
           "path": "/features",
           "value": "UsagePlans"
       }
   ]
   ```

## 创建使用计划
<a name="api-gateway-usage-plan-create"></a>

以下过程介绍如何创建使用计划。

------
#### [ AWS 管理控制台 ]

**创建使用计划**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在 API Gateway 主导航窗格中，选择**使用计划**，然后选择**创建使用计划**。  
![\[API 使用计划实体\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/api-gateway-new-console-usage-plan-keys-create-setup.png)

1. 对于**名称**，输入名称。

1.  （可选）对于**描述**，输入描述。

1. 默认情况下，使用计划会启用节流。为您的使用计划输入**速率**和**突增**。选择**节流**可关闭节流。

1. 默认情况下，使用计划会针对一个时间段启用配额。对于**请求**，输入用户在使用计划的时间段内，可以发出的请求总数。选择**配额**可关闭配额。

1. 选择**创建使用计划**。

------
#### [ AWS CLI ]

以下 [create-usage-plan](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-usage-plan.html) 命令创建在月初重置的使用计划：

```
aws apigateway create-usage-plan \
    --name "New Usage Plan" \
    --description "A new usage plan" \
    --throttle burstLimit=10,rateLimit=5 \
    --quota limit=500,offset=0,period=MONTH
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_CreateUsagePlan.html](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateUsagePlan.html) 以创建使用计划。

------

## 将阶段添加到使用计划中
<a name="api-gateway-usage-plan-add-stage"></a>

以下过程介绍如何将阶段添加到使用计划中。

------
#### [ AWS 管理控制台 ]

**将阶段添加到使用计划中**

1. 选择您的使用计划。

1.  在**关联的阶段**选项卡下，选择**添加阶段**。  
![\[将 API 阶段添加到使用计划中。\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/api-gateway-new-console-usage-plan-keys-create-add-stage.png)

1.  对于 **API**，选择一个 API。

1.  对于**阶段**，选择一个阶段。

1. （可选）要开启方法级别的节流，请执行以下操作：

   1. 选择**方法级别节流**，然后选择**添加方法**。

   1. 对于**资源**，从您的 API 中选择一个资源。

   1. 对于**方法**，从您的 API 中选择一种方法。

   1.  为您的使用计划输入**速率**和**突增**。

1. 选择**添加至使用计划**。

------
#### [ AWS CLI ]

以下 [update-usage-plan](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-usage-plan.html) 命令将 API 的 `Prod` 阶段添加到使用计划中：

```
aws apigateway update-usage-plan \
    --usage-plan-id abc123 \
    --patch-operations op="add",path="/apiStages",value="a1b1c2:Prod"
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateUsagePlan.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateUsagePlan.html) 以更新使用计划。

------

## 将 API 密钥添加到使用计划中
<a name="api-gateway-usage-plan-add-key"></a>

以下过程说明如何将 API 密钥添加到使用计划中。

------
#### [ AWS 管理控制台 ]

**将密钥添加到使用计划中**

1. 在**关联的 API 密钥**选项卡下，选择**添加 API 密钥**。  
![\[API 使用计划实体\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/api-gateway-new-console-usage-plan-keys-create-add-key.png)

1. 

   1.  要将现有密钥与您的使用计划关联，请选择**添加现有密钥**，然后从下拉菜单中选择您的现有密钥。

   1. 要创建新 API 密钥，请选择**创建并添加新密钥**，然后创建新密钥。有关如何创建新密钥的更多信息，请参阅[创建 API 密钥](api-gateway-setup-api-keys.md#api-gateway-usage-plan-create-apikey)。

1. 选择**添加 API 密钥**。

------
#### [ AWS CLI ]

以下 [create-usage-plan-key](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-usage-plan-key.html) 命令将现有 API 密钥与使用计划相关联：

```
aws apigateway create-usage-plan-key \
    --usage-plan-id a1b2c3 \
    --key-type "API_KEY" \
    --key-id aaa111bbb
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_CreateUsagePlanKey.html](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateUsagePlanKey.html) 以将现有 API 密钥与使用计划关联。

还可以在导入 API 密钥时将其与使用计划直接关联。调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_ImportApiKeys.html](https://docs.aws.amazon.com/apigateway/latest/api/API_ImportApiKeys.html) 以直接向指定的使用计划添加一个或多个 API 密钥。请求负载应包含 API 密钥值、关联的使用计划标识符、布尔值标记 (用于表明已为使用计划启用密钥)，还可能包含 API 密钥名称和描述。

以下 `apikey:import` 请求示例将向一个使用计划 (用 `key` 进行标识) 添加三个 API 密钥 (用 `name`、`description` 和 `usageplanIds` 进行标识)：

```
POST /apikeys?mode=import&format=csv&failonwarnings=fase HTTP/1.1
Host: apigateway.us-east-1.amazonaws.com
Content-Type: text/csv
Authorization: ...

key,name, description, enabled, usageplanIds
abcdef1234ghijklmnop8901234567, importedKey_1, firstone,  tRuE, n371pt 
abcdef1234ghijklmnop0123456789, importedKey_2, secondone, TRUE, n371pt
abcdef1234ghijklmnop9012345678, importedKey_3,          , true, n371pt
```

因此，将创建三个 `UsagePlanKey` 资源并将其添加到 `UsagePlan`。

您也可以通过这种方式向多个使用计划添加 API 密钥。要执行此操作，请将每个 `usageplanIds` 列值更改为逗号分隔的字符串，其中包含选定的使用计划标识符并用引号引起来 (`"n371pt,m282qs"` 或 `'n371pt,m282qs'`)。

------

**注意**  
一个 API 密钥可与多个使用计划关联。一个使用计划可与多个阶段关联。但是，对于 API 的每个阶段，给定 API 密钥只能与一个使用计划关联。

# 在 API Gateway 中为 REST API 维护使用计划
<a name="api-gateway-usage-plan-manage-usage"></a>

维护使用计划涉及监控给定时间段内的已用配额和剩余配额，并（如果需要）将剩余配额扩展指定的量。以下过程介绍如何监控配额。

------
#### [ AWS 管理控制台 ]

**监控已用配额和剩余配额**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在 API Gateway 主导航窗格中，选择**使用计划**。

1. 选择一个使用计划。

1. 选择**关联的 API 密钥**选项卡，查看每个密钥在时间段内剩余的请求数。

1. （可选）选择**导出使用数据**，然后选择**开始日期**和**结束日期**。接下来，为导出的数据选择 **JSON** 或 **CSV** 格式，然后选择**导出**。

   以下示例显示了一个导出的文件。

   ```
   {
       "px1KW6...qBazOJH": [
         [
           0,
           5000
         ],
         [
           0,
           5000
         ],
         [
           0,
           10
         ]
       ]
     }
   ```

   示例中的使用率数据显示了某 API 客户端在 2016 年 8 月 1 日至 2016 年 8 月 3 日期间的每日使用率数据，由 API 密钥 (`px1KW6...qBazOJH`) 标识。每个每日使用率数据均显示已用配额和剩余配额。在本例中，订阅者尚未使用任何分配的配额，并且 API 所有者或管理员已在第三天将剩余配额从 5000 减至 10。

以下过程介绍如何修改配额。

**扩展剩余配额**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在 API Gateway 主导航窗格中，选择**使用计划**。

1. 选择一个使用计划。

1. 选择**关联的 API 密钥**选项卡，查看每个密钥在时间段内剩余的请求数。

1. 选择 API 密钥，然后选择**授予使用延期**。

1. 为**剩余请求**配额输入一个数字。对于使用计划中的时间段，您可以增加剩余的请求数或减少剩余的请求数。

1. 选择**更新配额**。

------
#### [ AWS CLI ]

以下 [update-usage-plan](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-usage-plan.html) 命令示例在使用计划中，添加、删除或修改方法级别的节流设置。

**注意**  
确保为您的 API 将 `us-east-1` 更改为相应的区域值。

要添加或替换用于限制单个资源和方法的速率限制，请执行以下操作：

```
aws apigateway --region us-east-1 update-usage-plan --usage-plan-id planId --patch-operations op="replace",path="/apiStages/apiId:stage/throttle/resourcePath/httpMethod/rateLimit",value="0.1"
```

要添加或替换用于限制单个资源和方法的突增限制，请执行以下操作：

```
aws apigateway --region us-east-1 update-usage-plan --usage-plan-id planId --patch-operations op="replace",path="/apiStages/apiId:stage/throttle/resourcePath/httpMethod/burstLimit",value="1"
```

要删除单个资源和方法的方法级别限制设置，请执行以下操作：

```
aws apigateway --region us-east-1 update-usage-plan --usage-plan-id planId --patch-operations op="remove",path="/apiStages/apiId:stage/throttle/resourcePath/httpMethod",value=""
```

要删除 API 的所有方法级别限制设置，请执行以下操作：

```
aws apigateway --region us-east-1 update-usage-plan --usage-plan-id planId --patch-operations op="remove",path="/apiStages/apiId:stage/throttle ",value=""
```

下面是使用 Pet Store 示例 API 的示例：

```
aws apigateway --region us-east-1 update-usage-plan --usage-plan-id planId --patch-operations op="replace",path="/apiStages/apiId:stage/throttle",value='"{\"/pets/GET\":{\"rateLimit\":1.0,\"burstLimit\":1},\"//GET\":{\"rateLimit\":1.0,\"burstLimit\":1}}"'
```

------
#### [ REST API ]

调用 [https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateUsagePlan.html](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateUsagePlan.html) 以维护使用计划。

------

# 使用 CloudFormation 创建和配置 API 密钥和使用计划。
<a name="api-key-usage-plan-cfn"></a>

 您可以使用 CloudFormation 对于 API 方法要求 API 密钥并为 API 创建使用计划。示例 CloudFormation 模板执行以下操作：
+ 使用 `GET` 和 `POST` 方法创建 API Gateway API。
+ `GET` 和 `POST` 方法需要 API 密钥。此 API 从每个传入请求的 `X-API-KEY` 标头接收密钥。
+ 创建 API 密钥。
+ 创建使用计划，以指定每月限额为每月 1000 个请求，节流速率限制为每秒 100 个请求，而节流突增限制为每秒 200 个请求。
+ 为 `GET` 方法指定每秒 50 个请求的方法级节流速率限制和每秒 100 个请求的方法级节流突增限制。
+ 将 API 阶段和 API 密钥与使用计划关联。

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
  KeyName:
    Type: String
    Default: MyKeyName
    Description: Name of an API key
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: keys-api
      ApiKeySourceType: HEADER
  PetsResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'pets'
  PetsMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: GET
      ApiKeyRequired: true
      AuthorizationType: NONE
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  PetsMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: POST
      ApiKeyRequired: true
      AuthorizationType: NONE
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - PetsMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
  UsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn:
      - ApiDeployment
    Properties:
      Description: Example usage plan with a monthly quota of 1000 calls and method-level throttling for /pets GET 
      ApiStages:
        - ApiId: !Ref Api
          Stage: !Sub '${StageName}'
          Throttle:
            "/pets/GET": 
              RateLimit: 50.0
              BurstLimit: 100
      Quota:
        Limit: 1000
        Period: MONTH
      Throttle:
        RateLimit: 100.0
        BurstLimit: 200
      UsagePlanName: "My Usage Plan"
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    Properties: 
      Description: API Key
      Name: !Sub '${KeyName}'
      Enabled: True
  UsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref ApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref UsagePlan
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 'https://${Api}.execute-api.${AWS::Region}.amazonaws.com/${StageName}'
```

# 配置一个将 API 密钥与 OpenAPI 定义结合使用的方法
<a name="api-key-usage-plan-oas"></a>

您可以使用 OpenAPI 定义来要求对方法使用 API 密钥。

对于每个方法，创建一个安全要求对象，来要求使用 API 密钥调用该方法。然后，在安全定义中定义 `api_key`。创建 API 后，将新的 API 阶段添加到您的使用计划中。

以下示例创建一个 API，并要求为 `POST` 和 `GET` 方法提供 API 密钥：

------
#### [ OpenAPI 2.0 ]

```
{
  "swagger" : "2.0",
  "info" : {
    "version" : "2024-03-14T20:20:12Z",
    "title" : "keys-api"
  },
  "basePath" : "/v1",
  "schemes" : [ "https" ],
  "paths" : {
    "/pets" : {
      "get" : {
        "responses" : { },
        "security" : [ {
          "api_key" : [ ]
        } ],
        "x-amazon-apigateway-integration" : {
          "type" : "http_proxy",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets/",
          "passthroughBehavior" : "when_no_match"
        }
      },
      "post" : {
        "responses" : { },
        "security" : [ {
          "api_key" : [ ]
        } ],
        "x-amazon-apigateway-integration" : {
          "type" : "http_proxy",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets/",
          "passthroughBehavior" : "when_no_match"
        }
      }
    }
  },
  "securityDefinitions" : {
    "api_key" : {
      "type" : "apiKey",
      "name" : "x-api-key",
      "in" : "header"
    }
  }
}
```

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "keys-api",
    "version" : "2024-03-14T20:20:12Z"
  },
  "servers" : [ {
    "url" : "{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "v1"
      }
    }
  } ],
  "paths" : {
    "/pets" : {
      "get" : {
        "security" : [ {
          "api_key" : [ ]
        } ],
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets/",
          "passthroughBehavior" : "when_no_match",
          "type" : "http_proxy"
        }
      },
      "post" : {
        "security" : [ {
          "api_key" : [ ]
        } ],
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets/",
          "passthroughBehavior" : "when_no_match",
          "type" : "http_proxy"
        }
      }
    }
  },
  "components" : {
    "securitySchemes" : {
      "api_key" : {
        "type" : "apiKey",
        "name" : "x-api-key",
        "in" : "header"
      }
    }
  }
}
```

------

# 在 API Gateway 中针对 REST API 测试使用计划
<a name="api-gateway-usage-plan-test-with-postman"></a>

为了举例说明，我们将使用在[教程：通过导入示例创建 REST API](api-gateway-create-api-from-example.md)中创建的 PetStore API。假定 API 被配置为使用 API 密钥 `Hiorr45VR...c4GJc`。以下步骤介绍如何测试使用计划。

**测试您的使用计划**
+ 使用 `GET` 查询参数对使用计划中的 API (例如 `/pets`) 的 Pets 资源 (`?type=...&page=...`) 发出 `xbvxlpijch` 请求：

  ```
  GET /testStage/pets?type=dog&page=1 HTTP/1.1
  x-api-key: Hiorr45VR...c4GJc
  Content-Type: application/x-www-form-urlencoded
  Host: xbvxlpijch.execute-api.ap-southeast-1.amazonaws.com
  X-Amz-Date: 20160803T001845Z
  Authorization: AWS4-HMAC-SHA256 Credential={access_key_ID}/20160803/ap-southeast-1/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-api-key, Signature={sigv4_hash}
  ```
**注意**  
必须将此请求提交至 API Gateway 的 `execute-api` 组件，并在所需的 `Hiorr45VR...c4GJc` 标头中提供所需的 API 密钥（例如 `x-api-key`）。

  成功的响应会返回 `200 OK` 状态代码以及包含来自后端的请求结果的负载。如果您忘记设置 `x-api-key` 标头或使用不正确的密钥进行设置，则会收到 `403 Forbidden` 响应。不过，如果您未将方法配置为需要 API 密钥，则可能会收到 `200 OK` 响应 (无论是否正确设置 `x-api-key` 标头)，并且会绕过使用计划的限制和配额限制。

  有时，当出现使 API Gateway 无法对请求实施使用计划限制或配额的内部错误时，API Gateway 将处理该请求，而不会应用使用计划中指定的限制或配额。不过，它会在 CloudWatch 中记录错误消息 `Usage Plan check failed due to an internal error`。您可以忽略此类偶尔出现的错误。

# 使用 API 密钥调用方法
<a name="api-gateway-api-key-call"></a>

请使用下列过程之一以在方法调用中使用以标头为源的 API 密钥或授权方返回的 API 密钥，具体取决于您选择的 API 密钥源类型：

**使用以标头为源的 API 密钥：**

1.  使用所需的 API 方法创建 API，然后将 API 部署到某个阶段。

1.  新建使用计划，或选择现有使用计划。将部署的 API 阶段添加到使用计划。为使用计划附加 API 密钥，或在计划中选择现有 API 密钥。请记下所选的 API 密钥值。

1.  设置 API 方法以获得 API 密钥。

1.  将此 API 重新部署到同一阶段。如果将此 API 部署到新阶段，请确保更新使用计划，附加新的 API 阶段。

1. 使用 API 密钥调用 API。以下示例 curl 命令使用 API 密钥，在 API 的 `prod` 阶段，在 `getUsers` 资源上调用 `GET` 方法。

   ```
   curl -H "X-API-Key: abcd1234" 'https://b123abcde4.execute-api.us-west-2.amazonaws.com/prod/getUsers' 
   ```

客户端现在可以调用 API 方法，同时为 `x-api-key` 标头提供所选的 API 密钥作为标头值。调用过程可能如下所示：

**使用以授权方为源的 API 密钥：**

1.  使用所需的 API 方法创建 API，然后将 API 部署到某个阶段。

1.  新建使用计划，或选择现有使用计划。将部署的 API 阶段添加到使用计划。为使用计划附加 API 密钥，或在计划中选择现有 API 密钥。请记下所选的 API 密钥值。

1.  创建基于令牌的 Lambda 授权方。包括，`usageIdentifierKey:{api-key}` 作为授权响应的根级属性。有关创建基于令牌的授权方的说明，请参阅[`TOKEN` 授权方 Lambda 函数示例](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-token-lambda-function-create)。

1.  设置 API 方法以获得 API 密钥，并针对这些方法启用 Lambda 授权方。

1.  将此 API 重新部署到同一阶段。如果将此 API 部署到新阶段，请确保更新使用计划，附加新的 API 阶段。

客户端现在可以调用获得了 API 密钥的方法，而无需明确提供 API 密钥。返回授权方的 API 密钥将自动使用。