

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

# 身份验证流程
<a name="amazon-cognito-user-pools-authentication-flow-methods"></a>

Amazon Cognito 用户池的身份验证过程最好可以描述为一个*流程*：用户首先做出初始选择，提交凭证，并响应额外的质询。当您在应用程序中实现托管登录身份验证时，Amazon Cognito 会自动管理这些提示和质询的流程。当您在应用程序后端使用 S AWS DK 实现流程时，必须构造请求逻辑，提示用户输入并响应挑战。

作为应用程序管理员，您的用户特征、安全需求和授权模型将帮助您确定允许用户如何登录。请思考以下问题。
+ 我是否要允许用户使用[其他身份提供者的凭据登录 (IdPs)](#amazon-cognito-user-pools-authentication-flow-methods-federated)？
+ [用户名和密码](#amazon-cognito-user-pools-authentication-flow-methods-password)是否足以作为身份证明？
+ 我的用户名密码身份验证请求是否可能被拦截？ 我的应用程序是否应该直接传输密码，还是应[通过哈希和加密盐协商完成身份验证](#amazon-cognito-user-pools-authentication-flow-methods-srp)？
+ 我是否要允许用户跳过密码输入，[直接接收一次性密码](#amazon-cognito-user-pools-authentication-flow-methods-passwordless)进行登录？
+ 我是否希望允许用户使用[指纹、面部识别或硬件安全密钥](#amazon-cognito-user-pools-authentication-flow-methods-passkey)登录？
+ 我是否需要启用[多重身份验证（MFA）](#amazon-cognito-user-pools-authentication-flow-methods-mfa)？如果需要，应在何时执行？
+ 我是否希望[在不重复提示输入凭证的情况下持久化用户会话](#amazon-cognito-user-pools-authentication-flow-methods-refresh)？
+ 我是否希望[将授权模型扩展到](#amazon-cognito-user-pools-authentication-flow-methods-custom) Amazon Cognito 内置功能之外？

当您回答了这些问题后，就可以学习如何激活相关功能，并在应用程序发起的身份验证请求中加以实现。

为用户设置登录流程后，您可以通过 API 操作请求来检查其当前状态的 MFA [和](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)基于选择的身份验证因素。[GetUserAuthFactors](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUserAuthFactors.html)此操作需要使用已登录用户的访问令牌进行授权，并返回该用户的身份验证因素及 MFA 设置。

**Topics**
+ [使用第三方登录 IdPs](#amazon-cognito-user-pools-authentication-flow-methods-federated)
+ [使用永久密码登录](#amazon-cognito-user-pools-authentication-flow-methods-password)
+ [使用永久密码和安全有效载荷登录](#amazon-cognito-user-pools-authentication-flow-methods-srp)
+ [使用一次性密码进行无密码登录](#amazon-cognito-user-pools-authentication-flow-methods-passwordless)
+ [使用密钥进行无密码登录 WebAuthn](#amazon-cognito-user-pools-authentication-flow-methods-passkey)
+ [登录后进行 MFA](#amazon-cognito-user-pools-authentication-flow-methods-mfa)
+ [刷新令牌](#amazon-cognito-user-pools-authentication-flow-methods-refresh)
+ [自定义身份验证](#amazon-cognito-user-pools-authentication-flow-methods-custom)
+ [用户迁移身份验证流程](#amazon-cognito-user-pools-user-migration-authentication-flow)

## 使用第三方登录 IdPs
<a name="amazon-cognito-user-pools-authentication-flow-methods-federated"></a>

Amazon Cognito 用户池充当 “用苹果登录”、“用亚马逊登录” 和 OpenID Connect (OIDC) 服务之间的 IdPs身份验证会话的中间代理。此过程也称为*联合登录* 或*联合身份验证*。联合身份验证不使用您在应用程序客户端中配置的任何内置身份验证流程。相反，您可以将已配置的用户池分配 IdPs 给您的应用程序客户端。当用户在托管登录页面选择其 IdP，或您的应用程序通过重定向到该 IdP 的登录页面来发起会话时，联合登录便会触发。

通过联合登录，您将主要身份验证因素和 MFA 身份验证因素委托给用户的 IdP。除非您[将联合用户与本地用户关联](cognito-user-pools-identity-federation-consolidate-users.md)，否则 Amazon Cognito 不会为该联合用户添加本节中提到的其他高级身份验证流程。未关联的联合用户虽有用户名，但其本质上是映射属性数据的存储，通常不会独立于基于浏览器的流程用于登录。

**实现资源**
+ [使用第三方身份提供者进行用户池登录](cognito-user-pools-identity-federation.md)

## 使用永久密码登录
<a name="amazon-cognito-user-pools-authentication-flow-methods-password"></a>

在 Amazon Cognito 用户池中，每个用户都有一个用户名。这可能是电话号码、电子邮件地址，或由用户选择或管理员提供的标识符。此类用户可使用用户名和密码登录，并可选择性地提供 MFA。用户池可通过公开的或经 IAM 授权的 API 操作及 SDK 方法执行用户名密码登录。您的应用程序可以直接将密码发送至用户池进行身份验证。您的用户池会使用其他质询或 JSON Web 令牌 (JWTs) 作为成功身份验证的结果进行响应。

------
#### [ Activate password sign-in ]

要激活使用用户名和密码的[基于客户端的身份验证](authentication-flows-selection-sdk.md#authentication-flows-selection-client)，请配置您的应用程序客户端以允许该方式。在 Amazon Cognito 控制台中，导航到用户池配置中**应用程序**下的**应用程序客户端**菜单。要为客户端移动应用程序或原生应用程序启用明文密码登录，请编辑应用程序客户端，并在**身份验证流程**下选择**使用用户名和密码登录：ALLOW\$1USER\$1PASSWORD\$1AUTH**。要为服务器端应用程序启用明文密码登录，请编辑应用程序客户端，并选择**使用服务器端管理凭证登录：ALLOW\$1ADMIN\$1USER\$1PASSWORD\$1AUTH**。

要激活使用用户名和密码的[基于选择的身份验证](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)，请配置您的应用程序客户端以允许该方式。编辑应用程序客户端，然后选择**基于选择的登录：ALLOW\$1USER\$1AUTH**。

![\[一张来自 Amazon Cognito 控制台的屏幕截图，展示了为应用程序客户端选择明文密码身份验证流程的选项。选项 ALLOW_USER_PASSWORD_AUTH、ALLOW_ADMIN_USER_PASSWORD_AUTH 和 ALLOW_USER_AUTH 已选中。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/screenshot-choose-password-admin-password-and-user-auth.png)


要验证密码身份验证在基于选择的身份验证流程中是否可用，请导航到**登录菜单**，查看**基于选择的登录选项**下的部分。如果**密码**在**可用选项**下可见，则可以使用明文密码身份验证进行登录。**密码**选项包括明文和 SRP 用户名密码身份验证变体。

![\[一张来自 Amazon Cognito 控制台的屏幕截图，展示了用户池在 USER_AUTH 基于选择的登录配置中的密码身份验证选项。“密码”选项显示为已启用。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/screenshot-password-flow-in-user-auth.png)


在[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)请求中`ExplicitAuthFlows`使用您的首选 username-and-password身份验证选项进行配置。

```
"ExplicitAuthFlows": [ 
   "ALLOW_USER_PASSWORD_AUTH",
   "ALLOW_ADMIN_USER_PASSWORD_AUTH",
   "ALLOW_USER_AUTH"
]
```

在[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)请求中，`Policies`使用您想要支持的基于选择的身份验证流程进行配置。`AllowedFirstAuthFactors` 中的 `PASSWORD` 值同时包括明文密码和 SRP 身份验证流程选项。

```
"Policies": {
   "SignInPolicy": {
      "AllowedFirstAuthFactors": [
         "PASSWORD",
         "EMAIL_OTP",
         "WEB_AUTHN"
      ]
   }
}
```

------
#### [ Choice-based sign-in with a password ]

要使用用户名密码身份验证让用户登录应用程序，请按以下方式配置您的[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)或[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)请求的正文。如果当前用户符合使用用户名密码身份验证的条件，该登录请求将成功，或继续进入下一个质询。否则，系统将返回一份可用的主要因素身份验证质询列表。以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "PREFERRED_CHALLENGE" : "PASSWORD",
      "PASSWORD" : "[User's password]"
   },
   "ClientId": "1example23456789"
}
```

您也可以省略 `PREFERRED_CHALLENGE` 值，然后将收到一个响应，其中包含该用户符合条件的登录因素列表。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser"
   },
   "ClientId": "1example23456789"
}
```

如果您未提交首选质询，或所提交的用户不符合其首选质询的条件，Amazon Cognito 将在 `AvailableChallenges` 中返回一个可用选项列表。如果`AvailableChallenges`包含 o `ChallengeName` `PASSWORD` f，则可以使用以下格式的[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)或[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)质询响应继续进行身份验证。您必须传递一个 `Session` 参数，将该质询响应与初始登录请求的 API 响应关联起来。以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "ChallengeName": "PASSWORD",
   "ChallengeResponses": { 
      "USERNAME" : "testuser",
      "PASSWORD" : "[User's Password]"
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response"
}
```

对于符合条件且成功的首选质询请求，以及 `PASSWORD` 质询响应，Amazon Cognito 会返回令牌，或要求用户完成额外的质询，例如多重身份验证（MFA）。

------
#### [ Client-based sign-in with a password ]

要使用用户名密码身份验证让用户登录到客户端应用程序，请按以下方式配置请求的正文。[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "AuthFlow": "USER_PASSWORD_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "PASSWORD" : "[User's password]"
   },
   "ClientId": "1example23456789"
}
```

要使用用户名密码身份验证让用户登录服务器端应用程序，请按以下方式配置请求的正文。[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)您的应用程序必须使用 AWS 凭证签署此请求。以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "AuthFlow": "ADMIN_USER_PASSWORD_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "PASSWORD" : "[User's password]"
   },
   "ClientId": "1example23456789"
}
```

对于成功的请求，Amazon Cognito 会返回令牌，或要求用户完成额外的质询，例如多重身份验证（MFA）。

------

## 使用永久密码和安全有效载荷登录
<a name="amazon-cognito-user-pools-authentication-flow-methods-srp"></a>

用户池中的另一种用户名密码登录方式是使用安全远程密码（SRP）协议。该选项会发送对密码的“知识证明”，即一个密码哈希值和一个加密盐，供用户池进行验证。由于发送给 Amazon Cognito 的请求中不包含任何可读的密钥信息，因此您的应用程序是能够处理用户输入密码的唯一实体。SRP 身份验证涉及数学计算，建议使用 SDK 中可导入的现有组件来实现。SRP 通常在客户端应用程序（如移动应用程序）中实现。有关该协议的更多信息，请参阅 [The Stanford SRP Homepage](http://srp.stanford.edu/)。[维基百科](https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol)也提供了相关资源和示例。此外，[多种公开的库](https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol#Implementations)可用于在您的身份验证流程中执行 SRP 计算。

Amazon Cognito 身份验证 initiate-challenge-respond顺序使用 SRP 验证用户及其密码。您必须先配置用户池和应用程序客户端以支持 SRP 身份验证，然后在应用程序中实现登录请求与质询响应的逻辑。您的 SRP 库可生成随机数和计算值，用以向用户池证明您持有用户的密码。应用程序需将这些计算得出的值填入 Amazon Cognito 用户池 API 操作或 SDK 方法中用于身份验证的 JSON 格式的 `AuthParameters` 和 `ChallengeParameters` 字段。

------
#### [ Activate SRP sign-in ]

要激活使用用户名和 SRP 的[基于客户端的身份验证](authentication-flows-selection-sdk.md#authentication-flows-selection-client)，请配置您的应用程序客户端以允许该方式。在 Amazon Cognito 控制台中，导航到用户池配置中**应用程序**下的**应用程序客户端**菜单。要为客户端移动应用程序或原生应用程序启用 SRP 登录，请编辑应用程序客户端，并在**身份验证流程**下选择**使用安全远程密码（SRP）登录：ALLOW\$1USER\$1SRP\$1AUTH**。

要激活使用用户名和 SRP 的[基于选择的身份验证](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)，请编辑您的应用程序客户端，并选择**基于选择的登录：ALLOW\$1USER\$1AUTH**。

![\[一张来自 Amazon Cognito 控制台的屏幕截图，展示了为应用程序客户端选择安全远程密码身份验证流程的选项。选项 ALLOW_USER_SRP_AUTH 和 ALLOW_USER_AUTH 已选中。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/screenshot-choose-SRP-and-user-auth.png)


要验证 SRP 身份验证在基于选择的身份验证流程中是否可用，请导航到**登录菜单**，查看**基于选择的登录选项**下的部分。如果**密码**在**可用选项**下可见，则可以使用 SRP 身份验证进行登录。**密码**选项包括明文和 SRP 用户名密码身份验证变体。

![\[一张来自 Amazon Cognito 控制台的屏幕截图，展示了用户池在 USER_AUTH 基于选择的登录配置中的密码身份验证选项。“密码”选项显示为已启用。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/screenshot-password-flow-in-user-auth.png)


在[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)请求中`ExplicitAuthFlows`使用您的首选 username-and-password身份验证选项进行配置。

```
"ExplicitAuthFlows": [ 
   "ALLOW_USER_SRP_AUTH",
   "ALLOW_USER_AUTH"
]
```

在[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)请求中，`Policies`使用您想要支持的基于选择的身份验证流程进行配置。`AllowedFirstAuthFactors` 中的 `PASSWORD` 值同时包括明文密码和 SRP 身份验证流程选项。

```
"Policies": {
   "SignInPolicy": {
      "AllowedFirstAuthFactors": [
         "PASSWORD",
         "EMAIL_OTP",
         "WEB_AUTHN"
      ]
   }
}
```

------
#### [ Choice-based sign-in with SRP ]

要让用户通过 SRP 使用用户名密码身份验证登录应用程序，请按以下方式配置您的[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)或[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)请求的正文。如果当前用户符合使用用户名密码身份验证的条件，该登录请求将成功，或继续进入下一个质询。否则，系统将返回一份可用的主要因素身份验证质询列表。以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "PREFERRED_CHALLENGE" : "PASSWORD_SRP",
      "SRP_A" : "[g^a % N]"
   },
   "ClientId": "1example23456789"
}
```

您也可以省略 `PREFERRED_CHALLENGE` 值，然后将收到一个响应，其中包含该用户符合条件的登录因素列表。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser"
   },
   "ClientId": "1example23456789"
}
```

如果您未提交首选质询，或所提交的用户不符合其首选质询的条件，Amazon Cognito 将在 `AvailableChallenges` 中返回一个可用选项列表。如果`AvailableChallenges`包含 o `ChallengeName` `PASSWORD_SRP` f，则可以使用以下格式的[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)或[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)质询响应继续进行身份验证。您必须传递一个 `Session` 参数，将该质询响应与初始登录请求的 API 响应关联起来。以下参数集合是登录所需的最低要求。此外还支持其他参数。

```
{
   "ChallengeName": "PASSWORD_SRP",
   "ChallengeResponses": { 
      "USERNAME" : "testuser",
      "SRP_A" : "[g^a % N]"
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response"
}
```

Amazon Cognito 会对符合条件的首选质询请求以及 `PASSWORD_SRP` 质询响应返回一个 `PASSWORD_VERIFIER` 质询。您的客户必须完成 SRP 计算并回应[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)或[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)请求中的质疑。

```
{
   "ChallengeName": "PASSWORD_VERIFIER",
   "ChallengeResponses": { 
      "PASSWORD_CLAIM_SIGNATURE" : "string",
      "PASSWORD_CLAIM_SECRET_BLOCK" : "string",
      "TIMESTAMP" : "string"
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response]"
}
```

在成功响应 `PASSWORD_VERIFIER` 质询后，Amazon Cognito 会颁发令牌，或要求用户完成另一项必需的质询，例如多重身份验证（MFA）。

------
#### [ Client-based sign-in with SRP ]

SRP 身份验证更常用于客户端身份验证，而非服务器端。但是，您可以将 SRP 身份验证与[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)一起使用。要将用户登录到应用程序，请按如下方式配置 `InitiateAuth` 或 `AdminInitiateAuth` 请求的正文。以下参数集合是登录所需的最低要求。此外还支持其他参数。

客户端通过将生成元 *g*（模 N）的幂次提升到一个秘密随机整数 *a* 来生成 `SRP_A`。

```
{
   "AuthFlow": "USER_SRP_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "SRP_A" : "[g^a % N]"
   },
   "ClientId": "1example23456789"
}
```

Amazon Cognito 以 `PASSWORD_VERIFIER` 质询进行响应。您的客户必须完成 SRP 计算并回应[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)或[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)请求中的质疑。

```
{
   "ChallengeName": "PASSWORD_VERIFIER",
   "ChallengeResponses": { 
      "PASSWORD_CLAIM_SIGNATURE" : "string",
      "PASSWORD_CLAIM_SECRET_BLOCK" : "string",
      "TIMESTAMP" : "string"
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response]"
}
```

在成功响应 `PASSWORD_VERIFIER` 质询后，Amazon Cognito 会颁发令牌，或要求用户完成另一项必需的质询，例如多重身份验证（MFA）。

------

## 使用一次性密码进行无密码登录
<a name="amazon-cognito-user-pools-authentication-flow-methods-passwordless"></a>

密码可能会丢失或被盗。您可能希望仅验证用户是否能够访问已验证的电子邮件地址、电话号码或身份验证器应用程序。解决方法是采用*无密码* 登录。应用程序可以提示用户输入其用户名、电子邮件地址或电话号码。随后，Amazon Cognito 会生成一个一次性密码（OTP），即一个用户必须确认的验证码。用户成功提交该验证码后，身份验证即完成。

一次性密码 (OTP) 身份验证流程与用户池中必需的多因素身份验证 (MFA) 不兼容。当您设置为时，带有用户验证的密钥身份验证可以满足 MFA 要求。`FactorConfiguration` `MULTI_FACTOR_WITH_USER_VERIFICATION`如果 MFA 在您的用户池中是可选的，则激活 MFA 的用户将无法使用 OTP 第一因素登录。在 MFA 为可选的用户池中，没有 MFA 偏好的用户可以使用无密码身份验证因素进行登录。有关更多信息，请参阅 [有关用户池 MFA 的需知信息](user-pool-settings-mfa.md#user-pool-settings-mfa-prerequisites)。

当用户在无密码身份验证流程中正确输入其通过短信或电子邮件收到的验证码时，除了完成用户身份验证外，您的用户池还会将该用户原先未验证的电子邮件地址或电话号码属性标记为已验证。无论您是否将用户池配置为[自动验证](signing-up-users-in-your-app.md)电子邮件地址或电话号码，该用户的状态都会从 `UNCONFIRMED` 变更为 `CONFIRMED`。

**启用无密码登录后的新选项**  
当您在用户池中激活无密码身份验证时，某些用户流程的工作方式会发生变化。

1. 用户在注册时无需设置密码，并在登录时选择一个无密码身份验证因素。您也可以以管理员身份创建不带密码的用户。

1. [通过 CSV 文件导入](cognito-user-pools-using-import-tool.md)的用户可以立即使用无密码身份验证因素登录，无需在登录前设置密码。

1. 没有密码的用户可以提交不带`PreviousPassword`参数[ChangePassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ChangePassword.html)的 API 请求。

**使用自动登录 OTPs**  
通过电子邮件或短信注册并确认其用户帐户的用户 OTPs 可以使用与其确认消息匹配的无密码因素自动登录。在托管登录 UI 中，完成账户确认且符合使用确认码传送方式进行 OTP 登录的条件的用户，在提供确认码后会自动进入首次登录流程。在带有 AWS SDK 的自定义应用程序中，将以下参数传递给[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)或[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)操作。
+ [ConfirmSignUp](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html)API 响应中的`Session`参数作为`Session`请求参数。
+ 其中[AuthFlow](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-request-AuthFlow)之一`USER_AUTH`。

您可以传递值为 `EMAIL_OTP` 或 `SMS_OTP` 的 [PREFERRED\$1CHALLENGE](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-request-AuthParameters)，但这不是必需的。`Session` 参数提供身份验证的证明，当您传入有效的会话代码时，Amazon Cognito 会忽略 `AuthParameters`。

登录操作将返回表示身份验证成功的响应，如果满足以下条件 [AuthenticationResult](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AuthenticationResultType.html)，则不会再进行其他质询。
+ `Session` 代码有效且未过期。
+ 用户符合使用 OTP 身份验证方法的条件。

------
#### [ Activate passwordless sign-in ]

**控制台**  
要激活无密码登录，请先配置您的用户池，以允许使用一种或多种无密码类型作为主要登录方式，然后配置您的应用程序客户端以允许 `USER_AUTH` 身份验证流程。在 Amazon Cognito 控制台中，导航到用户池配置中**身份验证**下的**登录**菜单。编辑**基于选择的登录选项**，然后选择**电子邮件消息一次性密码**或 **SMS 消息一次性密码**。您可以同时激活这两个选项。保存更改。

导航到**应用程序客户端**菜单，然后选择一个应用程序客户端或新建一个。选择**编辑**，然后选择**登录时选择身份验证类型：ALLOW\$1USER\$1AUTH**。

**API/SDK**  
在用户池 API 中，`SignInPolicy`使用[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)请求中的相应无密码选项进行配置。

```
"SignInPolicy": { 
    "AllowedFirstAuthFactors": [ 
        "EMAIL_OTP",
        "SMS_OTP"
    ]
}
```

使用[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)请求中的必填选项配置您的应用程序客户端`ExplicitAuthFlows`。

```
"ExplicitAuthFlows": [ 
   "ALLOW_USER_AUTH"
]
```

------
#### [ Sign in with passwordless ]

无密码登录没有可在和中指定的[基于客户端`AuthFlow`的](authentication-flows-selection-sdk.md#authentication-flows-selection-client)登录方式。[InitiateAuth[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)OTP 身份验证仅在[基于选择](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)`AuthFlow`的情况下可用`USER_AUTH`，您可以在其中请求首选登录选项或从用户的登录选项中选择无密码选项。[AvailableChallenges](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-response-AvailableChallenges)要将用户登录到应用程序，请按如下方式配置 `InitiateAuth` 或 `AdminInitiateAuth` 请求的正文。以下参数集合是登录所需的最低要求。此外还支持其他参数。

在此示例中，我们不知道用户想要通过哪种方式登录。如果我们添加一个 `PREFERRED_CHALLENGE` 参数并且用户可以使用该首选质询，则 Amazon Cognito 将返回该质询。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser"
   },
   "ClientId": "1example23456789"
}
```

您也可以在本例中向 `AuthParameters` 添加 `"PREFERRED_CHALLENGE": "EMAIL_OTP"` 或 `"PREFERRED_CHALLENGE": "SMS_OTP"`。如果用户符合该首选方式的使用条件，您的用户池会立即向该用户的电子邮件地址或电话号码发送验证码，并返回 `"ChallengeName": "EMAIL_OTP"` 或 `"ChallengeName": "SMS_OTP"`。

如果您没有指定首选质询，Amazon Cognito 会返回一个 `AvailableChallenges` 参数。

```
{
   "AvailableChallenges": [ 
      "EMAIL_OTP", 
      "SMS_OTP",
      "PASSWORD"
    ],
   "Session": "[Session ID]"
}
```

该用户符合以下登录方式的条件：通过电子邮件消息 OTP 进行无密码登录、通过短信 OTP 进行无密码登录以及使用用户名密码登录。您的应用程序可以提示用户选择其中一种方式，也可以根据内部逻辑自动做出选择。然后，它继续执行选择挑战的[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)或[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)请求。假设用户希望使用电子邮件消息一次性密码完成无密码身份验证。

```
{
   "ChallengeName": "SELECT_CHALLENGE",
   "ChallengeResponses": { 
      "USERNAME" : "testuser",
      "ANSWER" : "EMAIL_OTP" 
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response]"
}
```

Amazon Cognito 会返回一个 `EMAIL_OTP` 质询，并向该用户已验证的电子邮件地址发送一个验证码。随后，您的应用程序必须再次对该质询作出响应。

如果您之前请求了 `EMAIL_OTP` 作为 `PREFERRED_CHALLENGE`，那么这同样会是接下来的质询响应步骤。

```
{
   "ChallengeName": "EMAIL_OTP",
   "ChallengeResponses": {
      "USERNAME" : "testuser", 
      "EMAIL_OTP_CODE" : "123456" 
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response]"
}
```

------

## 使用密钥进行无密码登录 WebAuthn
<a name="amazon-cognito-user-pools-authentication-flow-methods-passkey"></a>

通行密钥是安全的，对用户施加的工作量相对较低。通行密钥登录利用*身份验证器*，即用户可用于身份验证的外部设备。常规密码容易使用户面临钓鱼攻击、密码猜测和凭证盗用等漏洞。而使用通行密钥，您的应用程序可以利用手机及其他与信息系统连接或内置的设备中的高级安全措施。常见的通行密钥登录工作流通常始于向您的设备发起一次调用，以触发您的密码或*凭证* 管理器，例如 iOS 钥匙串或 Google Chrome 密码管理器。设备上的凭证管理器会提示用户选择一个通行密钥，并通过已有的凭据或设备解锁机制进行授权。现代手机配备了人脸识别、指纹识别、解锁图案等机制，其中一些机制可同时满足强身份验证中的*所知因素* 和*所有因素* 原则。在使用生物识别进行通行密钥身份验证的情况下，通行密钥还体现了*所是因素*.这一身份验证因素。

您可能希望用指纹、面部识别或安全密钥身份验证来替代密码。这是*密钥*或*WebAuthn*身份验证。应用程序开发人员通常允许用户在首次使用密码登录后注册生物识别设备。通过 Amazon Cognito 用户池，您的应用程序可以为用户配置此登录选项。当您的用户池设置为时，密钥身份验证可以满足多因素身份验证 (MFA) 要求。`FactorConfiguration` `MULTI_FACTOR_WITH_USER_VERIFICATION`在此配置中，带有用户验证的密钥身份验证算作多因素身份验证。

一次性密码 (OTP) 身份验证流程与用户池中必需的多因素身份验证 (MFA) 不兼容。当您设置为时，带有用户验证的密钥身份验证可以满足 MFA 要求。`FactorConfiguration` `MULTI_FACTOR_WITH_USER_VERIFICATION`如果 MFA 在您的用户池中是可选的，则激活 MFA 的用户将无法使用 OTP 第一因素登录。在 MFA 为可选的用户池中，没有 MFA 偏好的用户可以使用无密码身份验证因素进行登录。有关更多信息，请参阅 [有关用户池 MFA 的需知信息](user-pool-settings-mfa.md#user-pool-settings-mfa-prerequisites)。

### 通行密钥是什么？
<a name="amazon-cognito-user-pools-authentication-flow-methods-passkey-what-are"></a>

Passkeys 无需记住复杂的密码或输入 OTPs，从而简化了用户体验。Passkeys 基于[万维网联盟](https://www.w3.org/TR/webauthn-3/) (W3C) WebAuthn 和 FIDO（Fast Identity Online）联盟起草的 CTAP2 标准。*浏览器和平台实施这些标准，提供 APIs 网络或移动应用程序以启动密钥注册或身份验证过程，还提供用户界面供用户选择密钥身份验证器并与之交互。*

当用户在网站或应用程序中注册身份验证器时，身份验证器会创建公私密钥对。 WebAuthn 浏览器和平台将公钥提交给网站或应用程序的应用程序后端。身份验证器保留有关用户和应用程序的私钥 IDs、密钥和元数据。当用户希望使用已注册的身份验证器在注册的应用程序中进行身份验证时，该应用程序会生成一个随机质询。对该质询的响应是由身份验证器使用其为该用户和应用程序所保存的私有密钥生成的质询数字签名，并附带相关元数据。浏览器或应用程序平台接收到该数字签名后，会将其传递给应用程序后端。然后，应用程序使用之前存储的公有密钥来验证该签名。

**注意**  
您的应用程序不会收到用户向其身份验证器提供的任何身份验证密钥，也不会获得有关私有密钥的任何信息。

以下是一些当前市场上身份验证器的示例及其功能。某个身份验证器可能符合其中任意一类或多类。
+ 某些身份验证器在授予访问权限前会执行*用户验证*，使用的因素包括 PIN、面部或指纹等生物识别输入或密码，以确保只有合法用户才能授权操作。另一些身份验证器则不具备任何用户验证功能，还有一些在应用程序未要求时可以跳过用户验证。
+ 某些身份验证器（例如 YubiKey 硬件令牌）是便携式的。它们可通过 USB、蓝牙或 NFC 连接与设备通信。有些身份验证器则属于本地身份验证器，并与特定平台绑定，例如 PC 上的 Windows Hello 或 iPhone 上的 Face ID。如果设备足够小巧（如移动设备），设备绑定的身份验证器可由用户随身携带。有时，用户还能通过无线通信方式将硬件身份验证器连接到多个不同平台。例如，在桌面浏览器中，用户扫描一个二维码后，即可使用自己的智能手机作为通行密钥身份验证器。
+ 一些平台绑定的通行密钥会同步到云端，从而支持用户在多个设备上使用。例如，iPhone 上的 Face ID 通行密钥会将通行密钥元数据通过用户的 Apple 账户同步至 iCloud 钥匙串。这类通行密钥可在 Apple 设备之间实现无缝身份验证，不需要用户为每台设备单独注册。1Password、Dashlane 和 Bitwarden 等基于软件的身份验证器应用程序，也会在用户安装了该应用程序的所有平台上同步通行密钥。

 WebAuthn 用术语来说，网站和应用程序是*依赖方*。每个通行密钥都与一个特定的依赖方 ID 关联，依赖方 ID 是一个统一标识符，代表接受该通行密钥进行身份验证的网站或应用程序。开发人员必须谨慎选择其依赖方 ID，以确保身份验证的范围恰当。典型的依赖方 ID 是 Web 服务器的根域名。使用该依赖方 ID 规范的通行密钥可用于该域及其所有子域的身份验证。当用户尝试访问的网站 URL 与依赖方 ID 不匹配时，浏览器和平台会拒绝通行密钥身份验证。类似地，对于移动应用程序，只有当应用程序路径出现在由该应用程序在依赖方 ID 所指定的路径下公开提供的 `.well-known` 关联文件中时，通行密钥才能被使用。

通行密钥具有*可发现性*。浏览器或平台可以自动识别并使用它们，无需用户手动输入用户名。当用户访问支持通行密钥身份验证的网站或应用程序时，可以从浏览器或平台已知的通行密钥列表中进行选择，也可以扫描二维码。

### Amazon Cognito 如何实现通行密钥身份验证？
<a name="amazon-cognito-user-pools-authentication-flow-methods-passkey-cognito"></a>

通行密钥是一项可选功能，在除**精简版**外的所有[功能计划](cognito-sign-in-feature-plans.md)中均可用。它仅支持[基于选择的身份验证流程](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)。使用[托管登录](authentication-flows-selection-managedlogin.md)时，Amazon Cognito 会处理通行密钥身份验证的逻辑。您还可以使用中的 [Amazon Cognito 用户池 API 在 AWS SDKs](#amazon-cognito-user-pools-authentication-flow-methods)应用程序后端进行密钥身份验证。

Amazon Cognito 可以识别使用两种非对称加密算法 (-7) 和 ES256 (-257) 中的任何一种创建的密钥。 RS256大多数身份验证器都支持这两种算法。默认情况下，用户可以设置任意类型的身份验证器，例如硬件令牌、移动智能手机或软件身份验证器应用程序。Amazon Cognito 目前不支持[证明](https://csrc.nist.gov/glossary/term/attestation)强制执行。

在用户池中，您可以将用户验证配置为首选或必需。在未提供值的 API 请求中，该选项默认选择首选，而在 Amazon Cognito 控制台中，该选项也默认选择首选。当您将用户验证设置为首选时，用户可以设置不具备用户验证功能的身份验证器，且注册和身份验证操作可在不执行用户验证的情况下成功完成。要强制在通行密钥注册和身份验证过程中进行用户验证，请将此设置更改为必需。

您在通行密钥配置中设置的依赖方（RP）ID 是一项关键决策。如果您未另行指定，且您的[域品牌版本](managed-login-branding.md)使用的是托管登录，则用户池默认会将您的[自定义域](cognito-user-pools-add-custom-domain.md)作为预期的 RP ID。如果您没有配置自定义域，也未另行指定 RP ID，则用户池默认使用您的[前缀域](cognito-user-pools-assign-domain-prefix.md)作为 RP ID。您也可以将 RP ID 配置为任意一个不在公共后缀列表（PSL）中的域名。您的 RP ID 条目适用于托管登录和 SDK 身份验证中的通行密钥注册与身份验证。在移动应用程序中，通行密钥仅在 Amazon Cognito 能够在以您的 RP ID 为域的路径下找到 `.well-known` 关联文件时才能正常工作。作为最佳实践，请在您的网站或应用程序公开上线前，确定并设置好依赖方 ID 的值。如果您更改了 RP ID，用户必须使用新的 RP ID 重新注册。

每个用户最多可以注册 20 个通行密钥。用户必须至少成功登录过您的用户池一次后，才能注册通行密钥。托管登录能大幅简化通行密钥的注册流程。当您为用户池和应用程序客户端启用通行密钥身份验证后，使用托管登录域的用户池会在最终用户注册新用户账户后，自动提示其注册通行密钥。您也可以在任意时间引导用户的浏览器跳转至托管登录页面，以完成通行密钥注册。用户必须先提供用户名，Amazon Cognito 才能启动通行密钥身份验证。托管登录会自动处理这一过程。登录页面会先提示用户输入用户名，验证该用户是否已注册至少一个通行密钥，然后提示其使用通行密钥登录。同样地，在基于 SDK 的应用程序中，也必须先提示用户输入用户名，并在身份验证请求中提供该用户名。

当您为用户池配置通行密钥身份验证，并且同时拥有自定义域和前缀域时，RP ID 默认会使用您自定义域的完全限定域名（FQDN）。要在 Amazon Cognito 控制台中将前缀域设置为 RP ID，请删除您的自定义域，或将前缀域的 FQDN 作为**第三方域**手动输入。

------
#### [ Activate passkey sign-in ]

**控制台**  
要激活通行密钥登录，请先配置您的用户池，以允许使用一种或多种无密码类型作为主要登录方式，然后配置您的应用程序客户端以允许 `USER_AUTH` 身份验证流程。在 Amazon Cognito 控制台中，导航到用户池配置中**身份验证**下的**登录**菜单。编辑**基于选择的登录选项**，然后将**通行密钥**添加到**可用选项**列表中。

导航到**身份验证方法**菜单并编辑**通行密钥**。
+ **用户验证**是一项设置，用于控制您的用户池是否要求通行密钥设备执行额外的检查，以确认当前用户有权使用通行密钥。要鼓励用户配置设备以支持用户验证，但不强制要求，请选择**首选**。要仅支持具备用户验证功能的设备，请选择**必需**。有关更多信息，请参阅 w3.org 上的[用户验证](https://www.w3.org/TR/webauthn-2/#user-verification)。
+ **依赖方 ID 的域**是应用程序将在用户的通行密钥注册请求中传递的标识符。它设定了与用户通行密钥颁发者的信任关系的目标。您的依赖方 ID 可以是：您的用户池的域，前提是   
**Cognito 域名**  
您的用户池中的 Amazon Cognito [前缀域](cognito-user-pools-assign-domain-prefix.md)。  
**自定义域**  
您的用户池的[自定义域](cognito-user-pools-add-custom-domain.md)。  
**第三方域**  
指用于不使用用户池托管登录页面的应用程序的域。此设置通常与没有[域](cognito-user-pools-assign-domain.md)的用户池相关联，这些用户池在后端使用 S AWS DK 和用户池 API 进行身份验证。

导航到**应用程序客户端**菜单，然后选择一个应用程序客户端或新建一个。选择**编辑**，在**身份验证流程**下，选择**登录时选择身份验证类型：ALLOW\$1USER\$1AUTH**。

**API/SDK**  
在用户池 API 中，`SignInPolicy`使用[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)请求中的相应密钥选项进行配置。通行密钥身份验证的 `WEB_AUTHN` 选项必须至少附带一个其他选项。通行密钥注册需要现有的身份验证会话。

```
"SignInPolicy": { 
    "AllowedFirstAuthFactors": [ 
        "PASSWORD",
        "WEB_AUTHN"
    ]
}
```

在[SetUserPoolMfaConfig](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserPoolMfaConfig.html#CognitoUserPools-SetUserPoolMfaConfig-request-WebAuthnConfiguration)请求的`WebAuthnConfiguration`参数中配置您的用户验证首选项和 RP ID。其中，`RelyingPartyId`（即通行密钥身份验证结果的预期目标）可以是您的用户池前缀域、自定义域，或您自行指定的其他域。

```
"WebAuthnConfiguration": { 
   "RelyingPartyId": "example.auth.us-east-1.amazoncognito.com",
   "UserVerification": "preferred",
   "FactorConfiguration": "SINGLE_FACTOR"
}
```

使用[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)请求中的必填选项配置您的应用程序客户端`ExplicitAuthFlows`。

```
"ExplicitAuthFlows": [ 
   "ALLOW_USER_AUTH"
]
```

------
#### [ Register a passkey (managed login) ]

托管登录负责处理用户通行密钥的注册。当您的用户池启用了通行密钥身份验证后，Amazon Cognito 会在用户注册新账户时提示其设置通行密钥。

当用户已完成注册但尚未设置通行密钥，或您作为管理员为其创建了账户时，Amazon Cognito 不会提示用户设置通行密钥。处于这种状态的用户必须先使用其他身份验证因素（例如密码或无密码 OTP）成功登录，才能注册通行密钥。

**注册通行密钥**

1. 将用户引导至您的[登录页面](authorization-endpoint.md)。

   ```
   https://auth.example.com/oauth2/authorize/?client_id=1example23456789&response_type=code&scope=email+openid+phone&redirect_uri=https%3A%2F%2Fwww.example.com
   ```

1. 处理用户的身份验证结果。在此示例中，Amazon Cognito 会将用户重定向到 `www.example.com`，并附带一个应用程序可用来换取令牌的授权码。

1. 将用户引导至您的注册通行密钥页面。用户浏览器中有一个 Cookie，用于维持其已登录会话。该通行密钥页面的 URL 需包含 `client_id` 和 `redirect_uri` 参数。Amazon Cognito 仅允许已通过身份验证的用户访问此页面。请先使用密码、电子邮件 OTP 或短信 OTP 让用户完成登录，然后调用符合以下模式的 URL。

   您还可以在此请求中添加其他[对端点授权](authorization-endpoint.md)参数，例如 `response_type` 和 `scope`。

   ```
   https://auth.example.com/passkeys/add?client_id=1example23456789&redirect_uri=https%3A%2F%2Fwww.example.com
   ```

------
#### [ Register a passkey (SDK) ]

您可以在[PublicKeyCreationOptions](https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialcreationoptions)对象中使用元数据注册密钥凭证。您可以使用已登录用户的凭证生成该对象，并将其以 API 请求的形式提交给用户的通行密钥颁发者。颁发者将返回一个确认密钥注册的 [RegistrationResponseJSON](https://www.w3.org/TR/webauthn-3/#dictdef-registrationresponsejson) 对象。

要开始通行密钥注册过程，请使用现有登录选项登录用户。使用当前用户的访问[令牌授权[StartWebAuthnRegistration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_StartWebAuthnRegistration.html)](authentication-flows-public-server-side.md#user-pool-apis-auth-unauth-token-auth)的 API 请求进行授权。以下是一个示例 `GetWebAuthnRegistrationOptions` 请求的正文。

```
{
   "AccessToken": "eyJra456defEXAMPLE"
}
```

您的用户池返回的响应中包含 `PublicKeyCreationOptions` 对象。请将该对象以 API 请求的方式发送给用户的颁发者。此对象提供公有密钥和依赖方 ID 等信息。颁发者随后将返回一个 `RegistrationResponseJSON` 对象。

在 [CompleteWebAuthnRegistration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CompleteWebAuthnRegistration.html)API 请求中显示注册响应，再次使用用户的访问令牌进行授权。当您的用户池返回一个 HTTP 200 响应且正文为空时，即表示该用户的通行密钥已注册。

------
#### [ Sign in with a passkey ]

无密码登录没有你可以在和`AuthFlow`中指定的密码。[InitiateAuth[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)相反，您必须声明 `AuthFlow` 为 `USER_AUTH`，然后请求一个登录选项，或根据用户池返回的响应选择您的无密码登录方式。要将用户登录到应用程序，请按如下方式配置 `InitiateAuth` 或 `AdminInitiateAuth` 请求的正文。以下参数集合是登录所需的最低要求。此外还支持其他参数。

在此示例中，我们知道用户希望使用通行密钥登录，因此我们添加了一个 `PREFERRED_CHALLENGE` 参数。

```
{
   "AuthFlow": "USER_AUTH",
   "AuthParameters": { 
      "USERNAME" : "testuser",
      "PREFERRED_CHALLENGE" : "WEB_AUTHN"
   },
   "ClientId": "1example23456789"
}
```

Amazon Cognito 以 `WEB_AUTHN` 质询进行响应。您的应用程序必须对该质询作出响应。向用户的通行密钥提供商发起一个登录请求。它将返回一个 [AuthenticationResponseJSON](https://www.w3.org/TR/webauthn-3/#dictdef-authenticationresponsejson) 对象。

```
{
   "ChallengeName": "WEB_AUTHN",
   "ChallengeResponses": {
      "USERNAME" : "testuser", 
      "CREDENTIAL" : "{AuthenticationResponseJSON}" 
   },
   "ClientId": "1example23456789",
   "Session": "[Session ID from the previous response]"
}
```

------

## 登录后进行 MFA
<a name="amazon-cognito-user-pools-authentication-flow-methods-mfa"></a>

您可以设置用户在通过用户名密码流程完成登录后，被提示进行额外的验证，例如通过电子邮件消息、短信或验证码生成应用程序提供的一次性密码。MFA 不同于使用一次性密码的无密码登录。但是，当您在用户池中`FactorConfiguration`配置`MULTI_FACTOR_WITH_USER_VERIFICATION`为时，带有用户验证功能的密钥可以满足 MFA 要求。`WebAuthnConfiguration`对于基于密码的流程，用户池中的 MFA 是一种质询-响应模型，在这种模型中，用户首先证明自己知道密码，然后证明他们有权访问注册的第二要素设备。

**实现资源**
+ [向用户池添加 MFA](user-pool-settings-mfa.md)

## 刷新令牌
<a name="amazon-cognito-user-pools-authentication-flow-methods-refresh"></a>

当您希望用户在无需重新输入凭证的情况下保持登录状态时，*刷新令牌* 是您的应用程序可用于持久化用户会话的工具。应用程序可以向您的用户池提供刷新令牌，并将其兑换为新的 ID 令牌和访问令牌。通过令牌刷新，您可以在无需用户干预的情况下，确保已登录用户仍处于活跃状态、获取更新后的属性信息，并更新访问控制权限。

**实现资源**
+ [刷新令牌](amazon-cognito-user-pools-using-the-refresh-token.md)

## 自定义身份验证
<a name="amazon-cognito-user-pools-authentication-flow-methods-custom"></a>

您可能希望为用户配置一种此处未列出的身份验证方法。您可以使用带有 Lambda 触发器的*自定义身份验证* 来实现这一点。在一系列 Lambda 函数中，Amazon Cognito 会发出一个质询，向用户提出一个用户必须回答的问题，验证回答的准确性，并确定是否应发出另一个质询。这些问题和回答可以包括安全问题、对 CAPTCHA 服务的请求、对外部 MFA 服务 API 的请求，或按顺序组合使用以上所有方式。

**实现资源**
+ [自定义身份验证质询 Lambda 触发器](user-pool-lambda-challenge.md)

### 自定义身份验证流程
<a name="amazon-cognito-user-pools-custom-authentication-flow"></a>

Amazon Cognito 用户池实现了使用自定义身份验证流程，这可以帮助您使用 AWS Lambda 触发器创建基于质询/响应的身份验证模型。

自定义身份验证流程可以自定义质询和响应周期，以满足不同需求。该流程首先调用 `InitiateAuth` API 操作，该调用指示将使用的身份验证类型并提供了所有初始身份验证参数。Amazon Cognito 将使用以下类型的信息之一响应 `InitiateAuth` 调用：
+ 用户质询及会话和参数。
+ 错误（如果用户未能通过身份验证）
+ ID、访问和刷新令牌（如果 `InitiateAuth` 调用中提供的参数足以使用户登录）。（通常，用户或应用程序必须首先应答质询，但这必须由您的自定义代码决定。）

 如果 Amazon Cognito 使用质询响应 `InitiateAuth` 调用，则应用程序将收集更多输入并调用 `RespondToAuthChallenge` 操作。此调用提供质询响应并将其传回会话。Amazon Cognito 对 `RespondToAuthChallenge` 的响应类似于对 `InitiateAuth` 调用的响应。如果用户已登录，Amazon Cognito 会提供令牌，如果用户未登录，则 Amazon Cognito 会提供另一个质询或错误。如果 Amazon Cognito 返回另一质询，则序列重复，应用程序调用 `RespondToAuthChallenge` 直到用户成功登录或返回错误。有关 `InitiateAuth` 和 `RespondToAuthChallenge` API 操作的详细信息，请参阅 [API 文档](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)。

### 自定义身份验证流程和质询
<a name="Custom-authentication-flow-and-challenges"></a>

应用程序可以启动自定义身份验证流程，具体方法是：调用 `InitiateAuth` 并将 `CUSTOM_AUTH` 用作 `Authflow`。借助自定义身份验证流程，三个 Lambda 触发器控制响应的质询和验证。
+ `DefineAuthChallenge` Lambda 触发器将以前的质询和响应的会话数组作为输入。然后，它生成下一个质询名称和布尔值，指示用户是否通过身份验证并且应被授予令牌。此 Lambda 触发器是一个状态机，可通过质询控制用户的路径。
+ `CreateAuthChallenge` Lambda 触发器将质询名称作为输入并生成质询和参数以评估响应。当 `DefineAuthChallenge` 返回 `CUSTOM_CHALLENGE` 作为下一次质询时，身份验证流程调用 `CreateAuthChallenge`。`CreateAuthChallenge` Lambda 触发器在质询元数据参数中传递下一个类型的质询。
+ `VerifyAuthChallengeResponse` Lambda 函数会评估响应并返回布尔值以表明响应是否有效。

自定义身份验证流程还可以使用内置质询的组合，例如 SRP 密码验证和通过短信进行的 MFA。它可以使用自定义质询，如验证码或秘密问题。

### 在自定义身份验证流程中使用 SRP 密码验证
<a name="Using-SRP-password-verification-in-custom-authentication-flow"></a>

如果您希望将 SRP 包含在自定义身份验证流程中，则您必须开始使用 SRP。
+ 要在自定义流程中启动 SRP 密码验证，应用程序将 `CUSTOM_AUTH` 作为 `Authflow` 来调用 `InitiateAuth`。在 `AuthParameters` 映射 中，来自应用程序的请求包括 `SRP_A:`（SRP A 值）和 `CHALLENGE_NAME: SRP_A`。
+ `CUSTOM_AUTH` 流会使用 `challengeName: SRP_A` 和 `challengeResult: true` 的初始会话调用 `DefineAuthChallenge` Lambda 触发器。您的 Lambda 函数使用 `challengeName: PASSWORD_VERIFIER`、`issueTokens: false` 和 `failAuthentication: false` 作出响应。
+  接下来，该应用程序必须使用 `challengeName: PASSWORD_VERIFIER` 和 `challengeResponses` 映射中 SRP 所需的其它参数调用 `RespondToAuthChallenge`。
+ 如果 Amazon Cognito 验证了密码，`RespondToAuthChallenge` 使用 `challengeName: PASSWORD_VERIFIER` 和 `challengeResult: true` 的第二个会话调用 `DefineAuthChallenge` Lambda 触发器。此时，`DefineAuthChallenge` Lambda 触发器可以使用 `challengeName: CUSTOM_CHALLENGE` 响应来开启自定义质询。
+ 如果为用户启用了 MFA，则在 Amazon Cognito 验证密码后，您的用户将被要求设置 MFA 或使用 MFA 登录。

**注意**  
Amazon Cognito 托管的登录网页无法激活 [自定义身份验证质询 Lambda 触发器](user-pool-lambda-challenge.md)。

有关 Lambda 触发器的更多信息，包括示例代码，请参阅[使用 Lambda 触发器自定义用户池工作流](cognito-user-pools-working-with-lambda-triggers.md)。

## 用户迁移身份验证流程
<a name="amazon-cognito-user-pools-user-migration-authentication-flow"></a>

用户迁移 Lambda 触发器可帮助您将用户从旧式用户管理系统迁移到您的用户池。如果选择 `USER_PASSWORD_AUTH` 身份验证流程，则用户在用户迁移过程中无需重置密码。此流程在身份验证期间通过加密的 SSL 连接向服务发送用户的密码。

所有用户均完成迁移后，请切换为更安全的 SRP 流程。SRP 流程不通过网络发送任何密码。

要了解有关 Lambda 触发器的更多信息，请参阅[使用 Lambda 触发器自定义用户池工作流](cognito-user-pools-working-with-lambda-triggers.md)。

有关使用 Lambda 触发器迁移用户的更多信息，请参阅[利用用户迁移 Lambda 触发器导入用户](cognito-user-pools-import-using-lambda.md)。