首页 > 解决方案 > 通过 HTTPS 调用使用用户名和密码的 AWS Cognito 用户池 InitiateAuth 的示例代码?

问题描述

我正在尝试使用 Cognito 用户池通过 HTTPS 调用对 PC 应用程序进行身份验证。我想获得各种令牌,然后我可以使用这些令牌来访问 AWS 资源,而无需在 PC 应用程序中存储 AWS 机密。

AWS 文档记录了InitiateAuth 方法并显示了AWS Endpoints,但如何通过 HTTPS 进行调用并不是很明显。大多数调用都需要 AWS 签名,但如果我只是提交用户名和密码,则 InitiateAuth 调用不应该。

标签: amazon-web-servicesamazon-cognito

解决方案


经过一番摸索,我能够使用 AWS CLI 通过以下命令成功获取令牌:

aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id the_cognito_client_id --auth-parameters USERNAME=the_users_email,PASSWORD=the_users_password

其中 the_cognito_client_id 是一个大约 26 个字符长的字符串,在 General Settings / App clients 下显示为 App client id。

请注意,默认情况下未启用 USER_PASSWORD_AUTH 流,因此您最初会收到一个错误。转到特定用户池的 Cognito 控制台并查找常规设置/应用程序客户端,单击特定应用程序客户端的“显示详细信息”,然后选中“启用基于用户名密码的身份验证 (ALLOW_USER_PASSWORD_AUTH)”并保存。

一旦您取回令牌并且您知道您的呼叫正在工作,您可以使用 aws history show 命令向您显示实际 https 呼叫的详细信息。第一次打电话

aws history show

您将收到一条消息

Could not locate history. Make sure cli_history is set to enabled in the ~/.aws/config file

转到该文件并添加

cli_history=enabled

然后,使用 cli 再次运行您的initial-auth 调用。然后,当你运行

aws history show  

您将获得有关如何拨打电话的详细信息。(此时,您可能会考虑删除 cli_history 设置,这样您以后就不会使用所有凭据记录所有呼叫。)您将看到

to URL: https://cognito-idp.us-east-1.amazonaws.com/

它告诉你要使用的 URL,你会看到它是一个 POST。您会注意到“InitiateAuth”不在该 URL 中的任何位置。但是,您将看到标题包括:

"X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth"

"Content-Type": "application/x-amz-json-1.1"

您需要这两个标头(包括非标准 Content-Type)才能使 HTTPS 调用正常工作。可以使用 Postman 将调用放在一起,虽然 Postman 不喜欢非标准的 Content-Type,所以你必须关闭标准的 Content-Type 并手动将这两个 header 添加到调用中。此时,Postman 也能够获得令牌。

Postman 还提供了导出到 CURL 功能(单击显示“代码”的链接),它为您提供:

curl --location --request POST 'https://cognito-idp.us-east-1.amazonaws.com/' \
--header 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
--header 'Content-Type: application/x-amz-json-1.1' \
--data-raw '{
    "AuthFlow": "USER_PASSWORD_AUTH",
    "AuthParameters": {
        "PASSWORD": "the_users_password",
        "USERNAME": "the_users_email"
    },
    "ClientId": "the_cognito_client_id"
}'

在命令行上提交它也会为您提供所需的令牌。

要使用刷新令牌进行刷新,只需使用 InitiateAuth,但 AuthFlow 是 REFRESH_TOKEN_AUTH 并且 AuthParameters 的唯一成员是 REFRESH_TOKEN(当然也就是 RefreshToken)

现在,我只需要弄清楚如何使用 HTTPS 进行 USER_SRP_AUTH。


推荐阅读