

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

# 重定向和授权端点
<a name="authorization-endpoint"></a>

`/oauth2/authorize` 端点是支持两个重定向目标的重定向端点。如果您在 URL 中包括 `identity_provider` 或 `idp_identifier` 参数，则它会静默地将用户重定向到该身份提供者（IdP）的登录页面。否则，它会使用您在请求中包括的相同 URL 参数重定向到 [登录端点](login-endpoint.md)。

授权端点将会重定向到托管登录或 IdP 登录页面。此端点上的用户会话的目的地是您的用户必须直接在其浏览器中与之交互的网页。

要使用 authorize 端点，请在 `/oauth2/authorize` 上使用为您的用户池提供有关以下用户池详细信息的信息的参数调用用户的浏览器。
+ 您希望登录到的应用程序客户端。
+ 您希望最终到达的回调 URL。
+ 您要在用户的访问令牌中请求的 OAuth 2.0 范围。
+ （可选）您希望用于登录的第三方 IdP。

您还可以提供 Amazon Cognito 用来验证传入声明的 `state` 和 `nonce` 参数。

## GET `/oauth2/authorize`
<a name="get-authorize"></a>

`/oauth2/authorize` 端点只支持 `HTTPS GET`。您的应用程序通常在用户的浏览器中发起此请求。您只能通过 HTTPS 向 `/oauth2/authorize` 端点发出请求。

您可以在 OpenID Connect（OIDC）标准的[授权端点](http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthorizationEndpoint)中详细了解授权端点的定义。

### 请求参数
<a name="get-authorize-request-parameters"></a>

**`response_type`**  
必需。  
响应类型。必须为 `code` 或 `token`。  
`response_type` 为 `code` 的成功请求返回授权代码授予。授权代码授予是 Amazon Cognito 附加到重定向 URL 的 `code` 参数。您的应用程序可以将包含 [令牌端点](token-endpoint.md)的代码交换为访问权限、ID 和刷新令牌。作为安全最佳实践，以及要为您的用户接收刷新令牌，请在您的应用程序中使用授权代码授予。  
`response_type` 为 `token` 的成功请求返回隐式授予。隐式授予是 Amazon Cognito 附加到您的重定向 URL 的 ID 和访问令牌。隐式授予的安全性较差，因为它会向用户公开令牌和潜在的识别信息。您可以在应用程序客户端的配置中停用对隐式授予的支持。

**`client_id`**  
必需。  
应用程序客户端 ID。  
`client_id` 的值必须是您在其中发出请求的用户池中应用程序客户端的 ID。您的应用程序客户端必须支持由 Amazon Cognito 本地用户或至少一个第三方 IdP 登录。

**`redirect_uri`**  
必需。  
在 Amazon Cognito 授权用户之后，身份验证服务器将浏览器重定向到的 URL。  
重定向统一资源标识符（URI）必须具有以下属性：  
+ 必须是绝对 URI。
+ 您必须已经将 URI 预注册到客户端。
+ 不能包含片段组件。
请参阅 [OAuth 2.0-重定向端点](https://tools.ietf.org/html/rfc6749#section-3.1.2)。  
Amazon Cognito 要求您的重新导向 URI 使用 HTTPS，但 `http://localhost` 除外，您可以将其设置为回调 URL 以进行测试。  
Amazon Cognito 还支持应用程序回调， URLs 例如。`myapp://example`

**`state`**  
可选，建议。  
当应用程序向请求添加 *state* 参数时，如果 `/oauth2/authorize` 端点重新导向您的用户，则 Amazon Cognito 将此参数的值返回给您的应用程序。  
将此值添加到您的请求中以防止 [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) 攻击。  
不能将 `state` 参数的值设置为 URL 编码的 JSON 字符串。要在 `state` 参数中传递与此格式匹配的字符串，请将该字符串编码为 base64，然后在应用程序中对其进行解码。

**`identity_provider`**  
可选。  
添加此参数可绕过托管登录并将您的用户重定向到提供商登录页面。*identity\$1provider* 参数的值是出现在您的用户池中的身份提供者（IdP）的名称。  
+ 对于社交提供者，您可以使用 *identity\$1provider* 值 `Facebook`、`Google`、`LoginWithAmazon` 和 `SignInWithApple`。
+ 对于 Amazon Cognito 用户池，使用值 `COGNITO`。
+ 对于 SAML 2.0 和 OpenID Connect (OIDC) 身份提供商 (IdPs)，请使用您在用户池中分配给 IdP 的名称。

**`idp_identifier`**  
可选。  
添加此参数以重定向到具有 *identity\$1provider* 名称的替代名称的提供程序。您可以 IdPs 从 Amazon Cognito 控制台的**社交和外部提供商菜单中输入 SAML 2.0 和** OIDC 的标识符。

**`scope`**  
可选。  
可以是任何系统预留范围或与客户端关联的自定义范围的组合。范围必须以空格分隔。系统预留范围为 `openid`、`email`、`phone`、`profile` 和 `aws.cognito.signin.user.admin`。使用的任意范围必须与客户端关联，否则将在运行时忽略。  
如果客户端不请求任何范围，则身份验证服务器使用与客户端关联的所有范围。  
如果请求 `openid` 范围，则只返回 ID 令牌。如果请求 `aws.cognito.signin.user.admin` 范围，则访问令牌只能用于 Amazon Cognito 用户池。如果同时请求了 `phone` 范围，则只能请求 `email`、`profile` 和 `openid` 范围。这些范围控制进入 ID 令牌中的声明。

**`code_challenge_method`**  
可选。  
用于生成质询的哈希协议。[PKCE RFC](https://tools.ietf.org/html/rfc7636) 定义两个方法：S256 和 plain；但是，Amazon Cognito 身份验证服务器仅支持 S256。

**`code_challenge`**  
可选。  
从 `code_verifier` 生成的代码交换的证明密钥（PKCE）质询。有关更多信息，请参阅 [在授权代码授予中使用 PKCE](using-pkce-in-authorization-code.md)。  
仅当您指定 `code_challenge_method` 参数时是必需的。

**`nonce`**  
可选。  
您可以添加到请求中的随机值。您提供的 nonce 值包含在 Amazon Cognito 发出的 ID 令牌中。为了防范重播攻击，您的应用程序可以检查 ID 令牌中的 `nonce` 声明并将其与您生成的声明进行比较。有关 `nonce` 声明的更多信息，请参阅《OpenID Connect 标准》**中的 [ID token validation](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation)（ID 令牌验证）。

**`lang`**  
可选。  
您想要显示用户交互式页面的语言。托管登录页面可以本地化，但托管 UI（经典）页面不能。有关更多信息，请参阅 [托管登录本地化](cognito-user-pools-managed-login.md#managed-login-localization)。

**`login_hint`**  
可选。  
要传递给授权服务器的用户名提示。您可以从用户那里收集用户名、电子邮件地址或电话号码，并允许目的地提供者预先填入用户的登录名。当您向 `oauth2/authorize` 端点提交 `login_hint` 参数，而没有提交 `idp_identifier` 或 `identity_provider` 参数时，托管登录会使用您的提示值填写用户名字段。您也可以将此参数传递给 [登录端点](login-endpoint.md) 并自动填入用户名值。  
当您的授权请求调用到 OIDC 的重定向时，Amazon IdPs Cognito 会向该第三方授权机构在请求中添加一个`login_hint`参数。你无法将登录提示转发给 SAML、Apple、Login With Amazon、Google 或 Facebook（Meta） IdPs。

**`prompt`**  
可选。  
一个 OIDC 参数，用于控制现有会话的身份验证行为。仅在托管登录品牌版本中可用，不适用于经典托管 UI。有关 OIDC 规范的更多信息，请参阅[身份验证请求](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest)。值 `none` 和 `login` 会影响用户池的身份验证行为。  
 IdPs 当用户选择向第三方提供商进行身份验证时，Amazon Cognito 会`none`将`prompt`除您的值之外的所有值转发给您。当用户访问的 URL 包含 `identity_provider` 或 `idp_identifier` 参数，或者当授权服务器将他们重定向到[登录端点](login-endpoint.md)，然后他们从可用按钮中选择 IdP 时，也会出现这种情况。  
**Prompt 参数值**    
`prompt=none`  
Amazon Cognito 会以静默方式继续对拥有经过身份验证的有效会话的用户进行身份验证。通过此提示，用户可以在用户池中的不同应用程序客户端之间进行静默身份验证。如果用户尚未通过身份验证，则授权服务器返回 `login_required` 错误。  
`prompt=login`  
Amazon Cognito 要求用户重新进行身份验证，即使他们已有会话。请在您想再次验证用户的身份时发送此值。拥有现有会话的经过身份验证的用户可以在不使该会话失效的情况下返回登录。当拥有现有会话的用户再次登录时，Amazon Cognito 会为他们分配一个新的会话 Cookie。也可以将此参数转发给您的 IdPs。 IdPs接受此参数的用户还会向用户请求新的身份验证尝试。  
`prompt=select_account`  
此值对本地登录没有影响，必须在重定向到 IdPs的请求中提交。当包含在您的授权请求中时，此参数会将 `prompt=select_account` 添加到 IdP 重定向目的地的 URL 路径。当 IdPs 支持此参数时，他们会要求用户选择他们想要登录的账户。  
`prompt=consent`  
此值对本地登录没有影响，必须在重定向到 IdPs的请求中提交。当包含在您的授权请求中时，此参数会将 `prompt=consent` 添加到 IdP 重定向目的地的 URL 路径。当 IdPs支持此参数时，他们会先征得用户同意，然后再重定向回您的用户池。
当您在请求中忽略 `prompt` 参数时，托管登录将遵循默认行为：除非用户的浏览器具有有效的托管登录会话 Cookie，否则用户必须登录。您可以使用空格字符分隔符合并 `prompt` 的多个值，例如 `prompt=login consent`。

**`resource`**  
可选。  
您要在 `aud` 声明中绑定到访问令牌的资源的标识符。当您包含此参数时，Amazon Cognito 会验证该值是否为 URL，并将生成的访问令牌的受众设置到请求的资源。您可以使用 URL 格式的标识符或您选择的 URL 请求用户池[资源服务器](cognito-user-pools-define-resource-servers.md)。此参数的值必须以 `https://`、`http://localhost` 或自定义 URL 模式（例如 `myapp://`）开头。  
资源绑定在 [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) 中定义。有关资源服务器和资源绑定的更多信息，请参阅[资源绑定](cognito-user-pools-define-resource-servers.md#cognito-user-pools-resource-binding)。

## 示例：授权代码授予
<a name="sample-authorization-code-grant"></a>

这是授权代码授予的示例请求。

以下请求会启动会话，以便检索您的用户在 `redirect_uri` 目的地传递给应用程序的授权代码。该会话请求的范围包括用户属性和对 Amazon Cognito 自助服务 API 操作的访问权限。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=openid+profile+aws.cognito.signin.user.admin
```

Amazon Cognito 身份验证服务器使用授权代码和状态重新导向回您的应用程序。授权代码的有效期为五分钟。

```
HTTP/1.1 302 Found
Location: https://www.example.com?code=a1b2c3d4-5678-90ab-cdef-EXAMPLE11111&state=abcdefg
```

## 示例：使用 PKCE 进行授权代码授予
<a name="sample-authorization-code-grant-with-pkce"></a>

此示例流程使用 [PKCE](using-pkce-in-authorization-code.md#using-pkce-in-authorization-code.title) 执行授权代码授予。

此请求会添加 `code_challenge` 参数。要完成令牌代码的交换，必须在向 `/oauth2/token` 端点发出的请求中包括 `code_verifier` 参数。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=aws.cognito.signin.user.admin&
code_challenge_method=S256&
code_challenge=a1b2c3d4...
```

授权服务器将授权代码和状态重定向回您的应用程序。您的应用程序处理授权码并将其交换为令牌。

```
HTTP/1.1 302 Found
Location: https://www.example.com?code=a1b2c3d4-5678-90ab-cdef-EXAMPLE11111&state=abcdefg
```

## 示例：使用 `prompt=login` 要求重新进行身份验证
<a name="sample-authorization-code-with-prompt-login"></a>

以下请求会添加一个 `prompt=login` 参数，要求用户重新进行身份验证，即使他们已有会话。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=openid+profile+aws.cognito.signin.user.admin&
prompt=login
```

授权服务器重定向到[登录端点](login-endpoint.md)，要求重新进行身份验证。

```
HTTP/1.1 302 Found Location: https://mydomain.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=1example23456789&redirect_uri=https://www.example.com&state=abcdefg&scope=openid+profile+aws.cognito.signin.user.admin&prompt=login
```

## 示例：使用 `prompt=none` 进行静默身份验证
<a name="sample-authorization-code-with-prompt-none"></a>

以下请求会添加一个 `prompt=none` 参数，用于静默检查用户是否有有效会话。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=openid+profile+aws.cognito.signin.user.admin&
prompt=none
```

当不存在有效会话时，授权服务器向重定向 URI 返回错误。

```
HTTP/1.1 302 Found Location: https://www.example.com?error=login_required&state=abcdefg
```

当存在有效会话时，授权服务器返回授权码。

```
HTTP/1.1 302 Found Location: https://www.example.com?code=AUTHORIZATION_CODE&state=abcdefg
```

## 示例：通过资源绑定进行授权码授予
<a name="sample-authorization-code-with-resource-binding"></a>

以下请求会添加一个 `resource` 参数，用于将访问令牌绑定到特定的资源服务器。生成的访问令牌将为目标 API 创建条件，以验证其是否是经过身份验证的用户请求的目标受众。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=solar-system-data-api.example.com/asteroids.add&
resource=https://solar-system-data-api.example.com
```

授权服务器返回授权码，从而生成 `aud` 声明为 `https://solar-system-data-api.example.com` 的访问令牌。

```
HTTP/1.1 302 Found Location: https://www.example.com?code=AUTHORIZATION_CODE&state=abcdefg
```

## 示例：不带 `openid` 范围的令牌（隐式）授权
<a name="sample-token-grant-without-openid-scope"></a>

此示例流程生成隐式授权，并 JWTs 直接返回到用户的会话。

请求的是从您的授权服务器进行隐式授权。这在访问令牌中请求授权用户配置文件进行自助操作的范围。

```
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=token&
client_id=1example23456789&
redirect_uri=https://www.example.com&
state=abcdefg&
scope=aws.cognito.signin.user.admin
```

授权服务器仅使用访问令牌重定向回您的应用程序。由于未请求 `openid` 范围，Amazon Cognito 不会返回 ID 令牌。此外，Amazon Cognito 不会在此流程中返回刷新令牌。

```
HTTP/1.1 302 Found
Location: https://example.com/callback#access_token=eyJra456defEXAMPLE&token_type=bearer&expires_in=3600&state=STATE
```

## 示例：带 `openid` 范围的令牌（隐式）授权
<a name="sample-token-grant-with-openid-scope"></a>

此示例流程生成隐式授权并将令牌返回到用户的浏览器。

请求的是从您的授权服务器进行隐式授权。这在访问令牌中请求授权访问用户属性和自助操作的范围。

```
GET
https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize? 
response_type=token& 
client_id=1example23456789& 
redirect_uri=https://www.example.com& 
state=abcdefg&
scope=aws.cognito.signin.user.admin+openid+profile
```

授权服务器重定向回您的应用程序，带有访问令牌和 ID 令牌（因为包括了 `openid` 范围）：

```
HTTP/1.1 302 Found
Location: https://www.example.com#id_token=eyJra67890EXAMPLE&access_token=eyJra12345EXAMPLE&token_type=bearer&expires_in=3600&state=abcdefg
```

## 负向响应的示例
<a name="get-authorize-negative"></a>

Amazon Cognito 可能会拒绝您的请求。失败的请求附带 HTTP 错误代码和相关描述，您可以使用这些信息来更正请求参数。以下是负向响应的示例。
+ 如果 `client_id` 和 `redirect_uri` 有效，但请求参数格式不正确，身份验证服务器会将该错误重定向到客户端的 `redirect_uri` 并在 URL 参数中附加错误消息。以下是错误格式的示例。
  + 该请求不包括 `response_type` 参数。
  + 授权请求提供了 `code_challenge` 参数，但没有提供 `code_challenge_method` 参数。
  + `code_challenge_method` 参数的值不是 `S256`。

  以下是使用了错误格式的示例请求的响应。

  ```
  HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request
  ```
+ 如果客户端在 `response_type` 中请求 `code` 或 `token`，但没有这些请求的权限，则 Amazon Cognito 授权服务器将 `unauthorized_client` 返回到客户端的 `redirect_uri`，如下所示：

  ```
  HTTP 1.1 302 Found Location: https://client_redirect_uri?error=unauthorized_client
  ```
+  如果客户端请求范围未知、格式错误或者无效，则 Amazon Cognito 授权服务器会将 `invalid_scope` 返回到客户端的 `redirect_uri`，如下所示：

  ```
  HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_scope
  ```
+ 如果服务器中有意外的错误，则授权服务器会将 `server_error` 返回到客户端的 `redirect_uri`。由于 HTTP 500 错误不会发送到客户端，所以在用户的浏览器中不会显示该错误。授权服务器返回以下错误。

  ```
  HTTP 1.1 302 Found Location: https://client_redirect_uri?error=server_error
  ```
+ 当 Amazon Cognito 通过联合身份验证向第三方 IdPs进行身份验证时，Amazon Cognito 可能会遇到连接问题，例如：
  + 如果从 IdP 处请求令牌时连接超时，身份验证服务器会将该错误重定向到客户端的 `redirect_uri`，如下所示：

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=Timeout+occurred+in+calling+IdP+token+endpoint
    ```
  + 如果在调用 `jwks_uri` 端点进行 ID 令牌验证时连接超时，身份验证服务器会重定向到客户端的 `redirect_uri`，并出现如下所示的错误：

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=error_description=Timeout+in+calling+jwks+uri
    ```
+ 通过联合第三方进行身份验证时 IdPs，提供商可能会返回错误响应。这可能是由于配置错误或其他原因而造成，例如以下原因：
  + 如果从其他提供商处收到错误响应，身份验证服务器会将该错误重定向到客户端的 `redirect_uri`，如下所示：

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=[IdP name]+Error+-+[status code]+error getting token
    ```
  + 如果从 Google 收到错误响应，身份验证服务器会将该错误重定向到客户端的 `redirect_uri`，如下所示：

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=Google+Error+-+[status code]+[Google-provided error code]
    ```
+ 如果 Amazon Cognito 在连接到外部 IdP 时遇到通信异常，则身份验证服务器会重定向到客户端的 `redirect_uri`，并显示以下错误消息：
  + 

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=Connection+reset
    ```
  + 

    ```
    HTTP 1.1 302 Found Location: https://client_redirect_uri?error=invalid_request&error_description=Read+timed+out
    ```