

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

# 特定于应用程序的应用程序客户端设置
<a name="user-pool-settings-client-apps"></a>

用户池应用程序客户端是用户池中的一项配置，它与一个通过 Amazon Cognito 进行身份验证的移动或 Web 应用程序进行交互。应用程序客户端可以调用经过授权和未经身份验证的 API 操作，并读取或修改用户的部分或全部属性。您的应用程序必须在操作中向应用程序客户端表明自己的身份，才能注册、登录和处理忘记的密码。这些 API 请求必须包括使用应用程序客户端 ID 进行自我识别以及使用可选客户端密钥进行授权的机制。您必须保护所有应用程序客户端 IDs 或密钥，以便只有经过授权的客户端应用程序才能调用这些未经身份验证的操作。此外，如果您将应用程序配置为使用 AWS 凭证签署经过身份验证的 API 请求，则必须保护您的凭据免受用户检查。

您可以为一个用户池创建多个应用程序。应用程序客户端可能链接到应用程序的代码平台，也可能链接到用户池中的单独租户。例如，您可以为服务器端应用程序和其他 Android 应用程序创建一个应用程序。每个应用程序都有各自的应用程序客户端 ID。

您可以在应用程序客户端级别应用以下用户池特征的设置：

1. [分析](cognito-user-pools-pinpoint-integration.md)

1. [托管登录](cognito-user-pools-managed-login.md) IdPs、授权类型 URLs、回调和自定义

1. [资源服务器和自定义范围](cognito-user-pools-define-resource-servers.md)

1. [威胁防护](cognito-user-pool-settings-threat-protection.md)

1. [属性读取和写入权限](user-pool-settings-attributes.md#user-pool-settings-attribute-permissions-and-scopes)

1. [令牌到期和撤销](amazon-cognito-user-pools-using-tokens-with-identity-providers.md)

1. [身份验证流程](authentication.md#amazon-cognito-user-pools-authentication-flow)

## 应用程序客户端类型
<a name="user-pool-settings-client-app-client-types"></a>

**在 Amazon Cognito 中创建应用程序客户端时，您可以根据标准 OAuth 客户端类型（**公共客户端**和机密客户端）预先填充选项。**使用**客户端密钥**配置**机密客户端** 有关客户端类型的更多信息，请参阅 [IETF RFC 6749 \$12.1](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1)。

**公有客户端**  
公有客户端在浏览器或移动设备上运行。由于它没有可信的服务器端资源，所以它没有客户端密钥。

**机密客户端**  
机密客户端拥有可以信任的服务器端资源，使用**客户端密钥**进行未经身份验证的 API 操作。该应用程序可在后端服务器上作为守护进程或 Shell 脚本运行。

**客户端密钥**  
客户端机密或客户端密码是一个固定字符串，您的应用程序必须在发送到应用程序客户端的所有 API 请求中使用该字符串。您的应用程序客户端必须有客户端密钥才能执行 `client_credentials` 授权。有关更多信息，请参阅 [IETF RFC 6749 \$12.3.1](https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1)。  
每个应用程序客户端一次最多可以拥有两个密钥，从而无需停机即可进行密钥轮换。在创建应用程序客户端时，您可以让 Amazon Cognito 生成密钥值，也可以提供自己的自定义密钥值。您在创建应用程序后无法更改密钥。您可以通过 [AddUserPoolClientSecret](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AddUserPoolClientSecret.html)API 操作添加第二个密钥来轮换密钥。添加密钥时，您可以让 Amazon Cognito 生成密钥值，也可以提供自己的自定义密钥值。要删除密钥，请使用 [DeleteUserPoolClientSecret](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DeleteUserPoolClientSecret.html)API 操作。您无法删除与应用程序客户端关联的唯一密钥。您也可以删除应用程序，以便阻止使用该应用程序客户端 ID 的应用程序的访问。  
当您为应用程序类型选择**传统 Web** 应用程序和 **M 应用程序选项时，Amazon Cognito 控制台会创建带有客户端密钥的achine-to-machine应用程序**客户端。选择以下选项之一来生成客户端密钥，或者使用编程方式创建客户端，[CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html)并将其设置`GenerateSecret`为`true`。

您可以将机密客户端和客户端密钥用于公有应用程序。使用 Amazon CloudFront 代理添加`SECRET_HASH`在途中。有关更多信息，请参阅博客上的[使用亚马逊 CloudFront 代理保护公共客户端 Amazon Cognito](https://aws.amazon.com/blogs/security/protect-public-clients-for-amazon-cognito-by-using-an-amazon-cloudfront-proxy/)。 AWS 

## JSON Web 令牌
<a name="user-pool-settings-client-app-token-types"></a>

亚马逊 Cognito 应用程序客户端可以发行以下类型的 JSON 网络令牌 (JWTs)。

**身份（ID）令牌**  
一份可验证的声明，表明您的用户是从用户池进行的身份验证。OpenID Connect (OIDC) 在 2.0 定义的访问和刷新[令牌标准中添加了 ID 令牌规范](https://openid.net/specs/openid-connect-core-1_0.html#IDToken)。 OAuth ID 令牌包含身份信息，例如用户属性，您的应用程序可以使用这些信息来创建用户个人资料和配置资源。请参阅[了解身份（ID）令牌](amazon-cognito-user-pools-using-the-id-token.md)了解更多信息。

**访问令牌**  
您的用户访问权限的可验证声明。访问令牌包含[作用域](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3)、OIDC 和 OAuth 2.0 的功能。您的应用程序可以为后端资源提供范围，并证明您的用户池已授权用户或计算机访问来自 API 的数据或它们自己的用户数据。具有*自定义范围*的访问令牌（通常来自 M2M 客户端凭证授权）用于授权访问资源服务器。请参阅[了解访问令牌](amazon-cognito-user-pools-using-the-access-token.md)了解更多信息。

**刷新令牌**  
一种加密的初始身份验证声明，当您的用户令牌到期时，您的应用程序可以将其提供给您的用户池。刷新令牌请求会返回新的未到期访问令牌和 ID 令牌。请参阅[刷新令牌](amazon-cognito-user-pools-using-the-refresh-token.md)了解更多信息。

您可以在 [Amazon Cognito](https://console.aws.amazon.com/cognito/v2/idp/user-pools) 控制台中，从用户池的**应用程序客户端**菜单为每个应用程序客户端设置这些令牌的到期时间。

## 应用程序客户端术语
<a name="cognito-user-pools-app-idp-settings-about"></a>

以下术语是 Amazon Cognito 控制台中应用程序客户端的可用属性。

**允许的回调 URLs**  
回调 URL 指示在用户成功登录之后将被重新导向到哪里。选择至少一个回调 URL。回调 URL 必须：  
+ 是绝对 URI。
+ 已预先向客户端注册。
+ 不包含片段组件。
请参阅 [OAuth 2.0-重定向端点](https://tools.ietf.org/html/rfc6749#section-3.1.2)。  
Amazon Cognito 要求使用 `HTTPS` 而不是 `HTTP`，但 `http://localhost`（仅用于测试目的）除外。  
还支持 URLs 诸如之`myapp://example`类的应用程序回调。

**允许注销 URLs**  
注销 URL 指示在您的用户注销后会被重定向到哪里。

**属性读取和写入权限**  
您的用户群可能有很多客户，每个客户都有自己的应用程序客户端，并且 IdPs。您可以将应用程序客户端配置为仅对与应用程序相关的用户属性具有读写权限。在 machine-to-machine（M2M）授权之类的情况下，您可以不授予对任何用户属性的访问权限。  

**属性读取和写入权限配置的注意事项**
+ 如果您创建应用程序客户端但不自定义属性读取和写入权限，Amazon Cognito 会向所有用户池属性授予读写权限。
+ 您可以授予对不可变[自定义属性](user-pool-settings-attributes.md#user-pool-settings-custom-attributes.title)的写入权限。创建或注册用户时，您的应用程序客户端可以将值写入不可变属性。此后，您将无法为用户的任何不可变自定义属性写入值。
+ 应用程序客户端必须拥有对用户池中必要属性的写入权限。Amazon Cognito 控制台会自动将必要属性设置为可写属性。
+ 您不能允许应用程序客户端对 `email_verified` 或 `phone_number_verified` 拥有写入权限。用户池管理员可以修改这些值。用户只能通过[属性验证](signing-up-users-in-your-app.md#allowing-users-to-sign-up-and-confirm-themselves.title)来更改这些属性的值。

**身份验证流程**  
您的应用程序客户端允许的登录方法。您的应用程序可以支持使用用户名和密码进行身份验证、电子邮件和短信、密钥身份验证器 OTPs、使用 Lambda 触发器的自定义身份验证以及令牌刷新。作为最佳安全实践，请在自定义构建的应用程序中使用 SRP 身份验证进行用户名和密码身份验证。

**自定义作用域**  
自定义范围是您在**资源服务器**中为自己的资源服务器定义的范围。格式为*resource-server-identifier*/*scope*。请参阅[作用域、M2M 和资源服务器](cognito-user-pools-define-resource-servers.md)。

**默认的重定向 URI**  
将用户身份验证请求中的`redirect_uri`参数替换为第三方 IdPs。使用[CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html)或 [UpdateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html)API 请求的`DefaultRedirectURI`参数配置此应用程序客户端设置。此 URL 还必须是应用程序客户端的 `CallbackURLs` 的成员。在以下情况下，Amazon Cognito 会将经过身份验证的会话重定向到此 URL：  

1. 您的应用程序客户端分配了一个[身份提供商](#app-client-terms-identity-provider)并 URLs定义了多个[回调](#app-client-terms-callback-urls)。如果身份验证请求不包括 `redirect_uri` 参数，则用户池会将对[授权服务器](authorization-endpoint.md)的身份验证请求重定向到默认的重定向 URI。

1. 您的应用程序客户端分配了一个[身份提供商](#app-client-terms-identity-provider)并 URLs定义了一个[回调](#app-client-terms-callback-urls)。在这种情况下，无需定义默认的回调 URL。不包括 `redirect_uri` 参数的请求会重定向到一个可用的回调 URL。

**身份提供者**  
您可以选择部分或全部用户池外部身份提供商 (IdPs) 来对用户进行身份验证。您的应用程序客户端还可以仅对用户池中的本地用户进行身份验证。当您将 IdP 添加到应用程序客户端时，可以生成指向 IdP 的授权链接，并将其显示在您的托管登录的登录页面上。您可以分配多个 IdPs，但必须至少分配一个。有关使用外部的更多信息 IdPs，请参阅[使用第三方身份提供者进行用户池登录](cognito-user-pools-identity-federation.md)。

**OpenID Connect 范围**  
选择以下一个或多个 `OAuth` 范围来指定可以为访问令牌请求的访问权限。  
+ `openid` 范围声明您要检索 ID 令牌和用户的唯一 ID。它还会请求全部或部分用户属性，具体取决于请求中的其他范围。除非您请求 `openid` 范围，否则 Amazon Cognito 不会返回 ID 令牌。`openid` 范围授权结构化 ID 令牌声明，例如过期时间和密钥 ID，并确定您在 [userInfo 端点](userinfo-endpoint.md) 的响应中收到的用户属性。
  + 当 `openid` 是您请求的唯一范围时，Amazon Cognito 会使用当前应用程序客户端可以读取的所有用户属性填充 ID 令牌。对仅具有此范围的访问令牌的 `userInfo` 响应将返回所有用户属性。
  + 当您使用其他范围（例如 `phone`、`email` 或 `profile`）请求 `openid` 时，ID 令牌和 `userInfo` 返回用户的唯一 ID 以及由其他范围定义的属性。
+ `phone` 范围授予对 `phone_number` 和 `phone_number_verified` 声明的访问权限。此范围只能通过 `openid` 范围来请求。
+ `email` 范围授予对 `email` 和 `email_verified` 声明的访问权限。此范围只能通过 `openid` 范围来请求。
+ 该`aws.cognito.signin.user.admin`范围允许访问需要访问令牌的 [Amazon Cognito 用户池 API 操作](authentication-flows-public-server-side.md#user-pools-API-operations)，例如[UpdateUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserAttributes.html)和。[VerifyUserAttribute](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifyUserAttribute.html)
+ `profile` 范围授予对客户端可读取的所有用户属性的访问权限。此范围只能通过 `openid` 范围来请求。
有关范围的更多信息，请参阅[标准 OIDC 范围](http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)列表。

**OAuth 拨款类型**  
 OAuth 授权是一种检索用户池令牌的身份验证方法。Amazon Cognito 支持以下类型的授权。要将这些 OAuth 授权集成到您的应用程序中，您必须向用户池中添加域名。  
**授予授权代码**  
授权码授权会生成一个代码，您的应用程序可以用它与[令牌端点](token-endpoint.md)交换用户池令牌。当您交换授权码时，您的应用程序会收到 ID、访问权限和刷新令牌。与隐式授权一样，这种 OAuth 流程发生在用户的浏览器中。授权码授权是 Amazon Cognito 提供的最安全的授权，因为令牌在用户的会话中不可见。相反，您的应用程序会生成返回令牌的请求，并可以将其缓存在受保护存储空间中。有关更多信息，请参阅 [IETF RFC 6749 \$11.3.1](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1) 中的*授权码*。
作为公共客户端应用程序的最佳安全实践，仅激活授权码授予 OAuth 流程，并实施代码交换证明密钥 (PKCE) 以限制令牌交换。通过 PKCE，客户端只有在向令牌端点提供与原始身份验证请求中相同的机密时，才能交换授权码。有关 PKCE 的更多信息，请参阅 [IETF RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)。
**隐式授予**  
隐式授权直接从[对端点授权](authorization-endpoint.md)向用户的浏览器会话提供访问权限和 ID 令牌，但不返回刷新令牌。隐式授权消除了向令牌端点提出单独请求的要求，但与 PKCE 不兼容，也不会返回刷新令牌。该授权适用于无法完成授权码授权的测试场景和应用程序架构。有关更多信息，请参阅 [IETF RFC 6749 \$11.3.2](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.2) 中的*隐式授权*。您可以在应用程序客户端中同时激活授权码授权和隐式授权，然后按需使用每个授权。
**客户端凭证授权**  
客户端凭证授予用于 machine-to-machine (M2M) 通信。授权码和隐式授权向经过身份验证的人类用户发放令牌。客户端凭证授权非交互式系统对 API 的基于范围的授权。您的应用程序可以直接从令牌端点请求客户端凭证并接收访问令牌。有关更多信息，请参阅 [IETF RFC 6749 \$11.3.4](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4) 中的*客户端凭证*。您只能在具有客户端机密且不支持授权码或隐式授权的应用程序客户端中激活客户端凭证授权。
由于您没有以用户身份调用客户端凭证流程，因此该授权只能向访问令牌添加*自定义*范围。自定义范围就是您为自己的资源服务器定义的范围。默认范围（例如 `openid` 和 `profile`）不适用于非人类用户。  
由于 ID 令牌是对用户属性的验证，因此它们与 M2M 通信无关，客户凭证授权也不会发放 ID 令牌。请参阅[作用域、M2M 和资源服务器](cognito-user-pools-define-resource-servers.md)。
客户凭证授予会增加您的 AWS 账单费用。有关更多信息，请参阅 [Amazon Cognito 定价](https://aws.amazon.com/cognito/pricing)。

## 创建应用程序客户端
<a name="cognito-user-pools-app-idp-settings-console-create"></a>

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

**创建应用程序客户端（控制台）**

1. 转到 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。如果出现提示，请输入您的 AWS 凭据。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或创建一个用户池。这两个选项都会提示您使用特定于应用程序的设置配置应用程序客户端。

1. 选择一种能反映您的应用程序架构的**应用程序类型**。

1. 使用友好的标识符**命名您的应用程序**。

1. 输入**返回 URL**。

1. 选择**创建应用程序客户端**。创建应用程序客户端后，您可以更改高级选项。

1. Amazon Cognito 将您返回到应用程序客户端详细信息。要访问应用程序的示例代码，请从**快速设置指南**选项卡中选择一个平台。

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

```
aws cognito-idp create-user-pool-client --user-pool-id MyUserPoolID --client-name myApp
```

**注意**  
使用 JSON 格式进行回调和注销 URLs ，以防止 CLI 将其视为远程参数文件：  

```
--callback-urls "["https://example.com"]"
--logout-urls "["https://example.com"]"
```

有关更多信息，请参阅 AWS CLI 命令参考：[create-user-pool-client](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/create-user-pool-client.html)

------
#### [ Amazon Cognito user pools API ]

生成 [CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html)API 请求。必须为所有您不想设置为默认值的参数指定一个值。

------

## 更新用户池应用程序客户端（AWS CLI 和 AWS API）
<a name="cognito-user-pools-app-idp-settings-cli-api-update-user-pool-client"></a>

在 AWS CLI，输入以下命令：

```
aws cognito-idp update-user-pool-client --user-pool-id  "MyUserPoolID" --client-id "MyAppClientID" --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows "code" "implicit" --allowed-o-auth-scopes "openid" --callback-urls "["https://example.com"]" --supported-identity-providers "["MySAMLIdP", "LoginWithAmazon"]"
```

如果命令成功，则 AWS CLI 返回确认信息：

```
{
    "UserPoolClient": {
        "ClientId": "MyClientID",
        "SupportedIdentityProviders": [
            "LoginWithAmazon",
            "MySAMLIdP"
        ],
        "CallbackURLs": [
            "https://example.com"
        ],
        "AllowedOAuthScopes": [
            "openid"
        ],
        "ClientName": "Example",
        "AllowedOAuthFlows": [
            "implicit",
            "code"
        ],
        "RefreshTokenValidity": 30,
        "AuthSessionValidity": 3,
        "CreationDate": 1524628110.29,
        "AllowedOAuthFlowsUserPoolClient": true,
        "UserPoolId": "MyUserPoolID",
        "LastModifiedDate": 1530055177.553
    }
}
```

有关更多信息，请参阅 AWS CLI 命令参考:[update-user-pool-client](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/update-user-pool-client.html).

AWS API: [UpdateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html)

## 获取有关用户池应用程序客户端（AWS CLI 和 AWS API）的信息
<a name="cognito-user-pools-app-idp-settings-cli-api-describe-user-pool-client"></a>

```
aws cognito-idp describe-user-pool-client --user-pool-id MyUserPoolID --client-id MyClientID
```

有关更多信息，请参阅 AWS CLI 命令参考:[describe-user-pool-client](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/describe-user-pool-client.html).

AWS API: [DescribeUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPoolClient.html)

## 列出用户池（AWS CLI 和 AWS API）中的所有应用程序客户端信息
<a name="cognito-user-pools-app-idp-settings-cli-api-list-user-pool-clients"></a>

```
aws cognito-idp list-user-pool-clients --user-pool-id "MyUserPoolID" --max-results 3
```

有关更多信息，请参阅 AWS CLI 命令参考:[list-user-pool-clients](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/list-user-pool-clients.html).

AWS API: [ListUserPoolClients](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUserPoolClients.html)

## 删除用户池应用程序客户端（AWS CLI 和 AWS API）
<a name="cognito-user-pools-app-idp-settings-cli-api-delete-user-pool-client"></a>

```
aws cognito-idp delete-user-pool-client --user-pool-id "MyUserPoolID" --client-id "MyAppClientID"
```

有关更多信息，请参阅 AWS CLI 命令参考：[delete-user-pool-client](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/delete-user-pool-client.html)

AWS API: [DeleteUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DeleteUserPoolClient.html)