当尝试调用 Amazon Cognito 用户池 API 时,出现了“Unable to verify secret hash for client<client-id>”错误。如何解决此错误?
简短描述
当用户池应用程序客户端在用户池中配置客户端密钥时,在 API 查询参数中需要一个 SecretHash 值。如果 API 查询参数中未提供密钥哈希值,则 Amazon Cognito 会返回 Unable to verify secret hash for client <client-id> 错误
以下示例说明如何创建 SecretHash 值并将其包含在 InitiateAuth 或 ForgotPassword API 调用中。
解决方案
**注意:**如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请确保您使用的是最新版本的 AWS CLI。
创建 SecretHash 值
按照计算 SecretHash 值中的说明进行操作。您需要您的应用程序客户端 ID、应用程序客户端密钥和 Amazon Cognito 用户池中用户的用户名。
-或-
要自动执行该流程,请执行以下操作:
1.如果您尚未安装 Python,请安装 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)
注意:在运行示例脚本之前替换以下值: 对于用户名,输入用户池中用户的用户名。对于app_client_id,输入用户池的应用程序客户端 ID。要获取密钥,请输入应用程序客户端的密钥。
3.运行以下命令来运行脚本:
python3 secret_hash.py <username> <app_client_id> <app_client_secret>
注意:在运行命令之前替换以下值: 如果您运行的是早于 Python 3.0 的 Python 版本,请将 python3 替换为 python。对于 secret_hash.py,输入示例脚本的文件名。对于用户名,输入用户池用户名。对于 app_client_id,输入您的应用程序客户端 ID。对于app_client_secret,输入应用程序客户端的密钥。
命令响应返回一个 SecretHash 值。
在 API 调用中包含 SecretHash 值
**注意:**如果您的应用程序客户端未配置应用程序客户端密钥,则无需在 Amazon Cognito API 调用中输入 SecretHash 值。有关更多信息,请参阅 Configuring a user pool app client。
将您创建的 SecretHash 值作为 SECRET_HASH 参数添加到 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"
}
}