当我尝试调用 Amazon Cognito 用户池 API 时,出现“无法验证客户端 <client-id> 的密钥哈希”错误。如何解决此错误?
简短描述
当用户池中的用户池应用程序客户端配置了客户端密钥时,API 的查询参数中需要 SecretHash 值。如果 API 查询参数中未提供密钥哈希,则 Amazon Cognito 会返回 Unable to verify secret hash for client <client-id> (无法验证客户端 <client-id> 的密钥哈希) 错误。
以下示例说明如何创建 SecretHash 值以及将其包含在 InitiateAuth 或 ForgotPassword API 调用中。
解决方法
注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时遇到错误,请确保您运行的是最新版本的 AWS CLI。
创建 SecretHash 值
按照计算 SecretHash 值中的说明进行操作。您将需要提供您的应用程序客户端 ID、应用程序客户端密钥和 Amazon Cognito 用户池中用户的用户名。
-或者-
要自动执行此流程,请执行以下操作:
1. 如果您尚未安装 Python,请进行安装。
2. 将以下示例 Python 脚本另存为 .py 文件:
import sys
import hmac, hashlib, base64
username = sys.argv[1]
app_client_id = sys.argv[2]
key = sys.argv[3]
message = bytes(sys.argv[1]+sys.argv[2],'utf-8')
key = bytes(sys.argv[3],'utf-8')
secret_hash = base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
print("SECRET HASH:",secret_hash)
**注意:**在运行示例脚本之前替换以下值:对于 username,请输入用户池中用户的用户名。对于 app_client_id,请输入用户池的应用程序客户端 ID。对于 key,请输入应用程序客户端的密钥。
3. 运行以下命令来运行脚本:
python3 secret_hash.py <username> <app_client_id> <app_client_secret>
注意:在运行命令之前替换以下值:如果您运行的 Python 版本早于 Python 3.0,请用 python 替换 python3。对于 secret_hash.py,请输入示例脚本的文件名。对于 username,请输入用户池用户名。对于 app_client_id,请输入您的应用程序客户端 ID 对于app_client_secret,请输入应用程序客户端的密钥。
命令响应返回 SecretHash 值。
在 API 调用中包含 SecretHash 值
**注意:**如果您的应用程序客户端未配置应用程序客户端密钥,则 Amazon Cognito API 调用中不需要 SecretHash 值。有关更多信息,请参阅配置用户池应用程序客户端。
将您创建为 SECRET_HASH 参数的 SecretHash 值添加到 API 调用的查询字符串参数中。
包含 SECRET_HASH 参数的示例 InitiateAuth API 调用
$ aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME=<username>,PASSWORD=<password>,SECRET_HASH=<secret_hash> --client-id <client-id>
示例 InitiateAuth API 调用响应
{
"ChallengeParameters": {},
"AuthenticationResult": {
"AccessToken": "<HIDDEN>",
"ExpiresIn": 3600,
"TokenType":
"Bearer",
"RefreshToken": "<HIDDEN>",
"IdToken": "<HIDDEN>"
}
}
**注意:**如果您使用的是 USER_PASSWORD_AUTH 身份验证流程,请确保已启用 ALLOW_USER_PASSWORD_AUTH。
包含 SECRET_HASH 参数的示例 ForgotPassword API 调用
$ aws cognito-idp forgot-password --client-id <client-id> --username <username> --secret-hash <secret-hash>
示例 ForgotPassword API 调用响应
{
"CodeDeliveryDetails": {
"Destination": "+***********",
"DeliveryMedium": "SMS",
"AttributeName": "phone_number"
}
}