

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 管理用户池令牌到期和缓存
<a name="amazon-cognito-user-pools-using-tokens-caching-tokens"></a>

每次您想要获取新的 JSON Web 令牌（JWT）时，应用程序都必须成功完成以下请求之一。
+ 从[令牌端点](token-endpoint.md)请求客户端凭证或授权码[授予](https://www.rfc-editor.org/rfc/rfc6749#section-1.3)。
+ 从您的托管登录页面请求隐式授权。
+ 在 Amazon Cognito API 请求中对本地用户进行身份验证，例如。[InitiateAuth](https://docs.amazonaws.cn/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)

您可以将用户池配置为将令牌设置为在数分钟、数小时或数天后过期。要确保应用程序的性能和可用性，请使用 Amazon Cognito 令牌至大约 75% 的令牌生命周期，并且仅在那时获取新令牌。您为应用程序构建的缓存解决方案可保持令牌可用，并可防止 Amazon Cognito 在您的请求速率过高时拒绝请求。客户端应用程序必须将令牌存储在内存缓存中。服务器端应用程序可以添加加密的缓存机制来存储令牌。

当您的用户池生成大量用户或 machine-to-machine活动时，您可能会遇到 Amazon Cognito 对您可以发出的令牌请求数量设定的限制。要减少您向 Amazon Cognito 端点发出的请求数量，可以安全地存储和重复使用身份验证数据，也可以实施指数回退和重试。

身份验证数据来自两类端点。Amazon Cognito [OAuth2.0 终端](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html)节点包括令牌终端节点，该终端节点为客户端凭证和托管登录授权码请求提供服务。[服务端点](https://docs.amazonaws.cn/general/latest/gr/cognito_identity.html#cognito_identity_your_user_pools_region)应答用户池 API 请求，例如 `InitiateAuth` 和 `RespondToAuthChallenge`。每种类型的请求都有自己的限制。有关限制的更多信息，请参阅[Amazon Cognito 中的限额](quotas.md)。

## 使用 Amazon API Gateway 缓存 machine-to-machine访问令牌
<a name="amazon-cognito-user-pools-using-tokens-caching-tokens-API-gateway"></a>

借助 API Gateway 令牌缓存，您的应用程序可以扩展以响应大于 Amazon Cognito OAuth 终端节点默认请求速率配额的事件。

![\[API Gateway 为 M2M 维护访问令牌缓存的示意图。API 代理处理令牌请求，如果已经有一个缓存的令牌有效，则返回缓存的令牌。\]](http://docs.amazonaws.cn/cognito/latest/developerguide/images/user-pools-m2m-caching.png)


您可以缓存访问令牌，以便您的应用程序仅在缓存的令牌过期时才请求新的访问令牌。否则，您的缓存端点会从缓存中返回一个令牌。这会阻止对 Amazon Cognito API 端点的其他调用。当您使用 Amazon API Gateway 作为 [令牌端点](token-endpoint.md)的代理时，您的 API 会响应大多数原本会计入您的请求配额的请求，从而避免由于速率限制而导致的请求失败。

以下基于 API Gateway 的解决方案提供了低延迟、低代码/无代码的令牌缓存实施。API Gateway APIs 在传输过程中进行加密，也可以选择静态加密。API Gateway 缓存非常适合 OAuth 2.0 [客户端凭证授予](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)，这是一种通常是大批量的授予类型，用于生成用于授权 machine-to-machine和微服务会话的访问令牌。在诸如流量激增导致您的微服务水平扩展的情况下，您最终可能会有许多系统使用相同的客户端凭据，但其数量超过用户池或应用程序客户端的 Amazon 请求速率限制。要保持应用程序可用性和低延迟，缓存解决方案是此类情况下的最佳实践。

在此解决方案中，您可以在 API 中定义一个缓存，以便为要在应用中请求的 OAuth 范围和应用程序客户端的每种组合存储单独的访问令牌。当您的应用程序发出与缓存键匹配的请求时，您的 API 会使用 Amazon Cognito 向与缓存键匹配的第一个请求颁发的访问令牌进行响应。当您的缓存键持续时间到期时，API 会将请求转发到令牌端点并缓存新的访问令牌。

**注意**  
您的缓存键持续时间必须短于应用程序客户端的访问令牌持续时间。

缓存密钥是您在请求正文`scope`参数中请求的 OAuth 作用域和请求`Authorization`标头的组合。`Authorization` 标头包含您的应用程序客户端 ID 和客户端密钥。您无需在应用程序中实施其他逻辑即可实施此解决方案。您只必须更新配置以更改用户池令牌端点的路径。

您也可以使用 [ElastiCache (Redis OSS)](https://docs.amazonaws.cn/elasticache/index.html) 实现令牌缓存。要使用 Amazon Identity and Access Management (IAM) 策略进行精细控制，请考虑 [Amazon DynamoDB](https://docs.amazonaws.cn/amazondynamodb/latest/developerguide/authentication-and-access-control.html#authentication) 缓存。

**注意**  
在 API Gateway 中缓存需要支付额外费用。[有关更多详细信息，请参阅定价。](https://www.amazonaws.cn/api-gateway/pricing)<a name="amazon-cognito-user-pools-using-tokens-caching-tokens-API-gateway-how-to"></a>

**使用 API Gateway 设置缓存代理**

1. 打开 [API Gateway 控制台](https://console.amazonaws.cn/apigateway/main/apis)，然后创建一个 REST API。

1. 在 **Resources**（资源）中，创建一个 POST 方法。

   1. 选择 HTTP **Integration type**（集成类型）。

   1. 选择 **Use HTTP proxy integration**（使用 HTTP 代理集成）。

   1. 输入 **Endpoint URL**（端点 URL）`https://<your user pool domain>/oauth2/token`。

1. 在 **Resources**（资源）中，配置缓存键。

   1. 编辑 POST 方法的 **Method request**（方法请求）。
**注意**  
此方法请求验证用于令牌请求中的 `client_secret_basic` 授权，其中客户端密钥被编码在 `Authorization` 请求标头中。对于使用 `client_secret_post` 授权方式对 JSON 请求正文的验证，应创建一个[数据模型](https://docs.amazonaws.cn/apigateway/latest/developerguide/models-mappings-models.html)，明确要求请求正文中必须包含 [client\$1secret](token-endpoint.md#post-token-request-parameters-in-body)。在此模型中，您的**请求验证程序**应**验证正文、查询字符串参数和标头**。

   1. 配置**请求验证程序**方法以**验证查询字符串参数和标头**。有关请求验证的更多信息，请参阅 *Amazon API Gateway 开发者指南*中的[请求验证](https://docs.amazonaws.cn/apigateway/latest/developerguide/api-gateway-method-request-validation.html)。

   1. 将您的 `scope` 参数和 `Authorization` 标头设置为缓存键。

      1. 将一个查询字符串添加到 **URL 查询字符串参数**。输入 `scope` 作为查询字符串的**名称**，然后选择**必填项**和**缓存**。

      1. 将一个标头添加到 **HTTP 请求标头**。输入 `Authorization` 作为请求标头的**名称**，然后选择**必填项**和**缓存**。

1. 在 **Stages**（阶段）中，配置缓存。

   1. 选择要修改的阶段，然后从**阶段详细信息**中选择**编辑**。

   1. 在**其他设置**下，对于**缓存设置**，开启**配置 API 缓存**选项。

   1. 选择 **Cache capacity**（缓存容量）。较高的缓存容量可以提高性能，但需要额外付费。

   1. 清除**需要授权**复选框。选择**继续**。

   1. API Gateway 仅将缓存策略应用于阶段级别的 GET 方法。您必须对 POST 方法应用缓存策略覆盖。

      展开您配置的阶段并选择 `POST` 方法。要为该方法创建缓存设置，请选择**创建覆盖**。

   1. 激活**启用方法缓存**选项。

   1. 输入 3600 秒的****缓存 time-to-live (TTL)****。选择**保存**。

1. 在 **Stages**（阶段）中，注意 **Invoke URL**（调用 URL）。

1. 更新您的应用程序，以将令牌请求发布到 API 的 **Invoke URL**（调用 URL）而不是用户池的 `/oauth2/token` 端点。