上次更新日期:2021 年 4 月 21 日
我想跟踪 Amazon Cognito 用户池中的用户用于登录我的应用程序的设备。该如何操作?
简短描述Amazon Cognito 可以跟踪和记住用户池中的用户用于登录的设备。通过启用设备记忆功能,您可以设置登录限制(例如,限制从某个设备登录)。或者,您可以让用户跳过同一设备上的重复登录。有关更多信息,请参阅指定用户池设备跟踪设置。
注意:记忆设备功能仅可用于 USER_SRP_AUTH 身份验证流程。此外,此功能需要为用户池启用多重身份验证 (MFA)。
记住设备是一个两步过程:
确认新的设备。从设备启动身份验证,然后使用 Amazon Cognito 进行确认以获取唯一的设备标识符。 验证已确认的设备。从已确认的设备启动身份验证,以在随后的登录尝试中跳过 MFA 步骤。 解决方法注意:以下说明概要描述了在应用程序客户端代码中进行的 Amazon Cognito API 调用。如果您使用的是客户端开发工具包,例如适用于 Android 或 iOS 的 AWS 移动开发工具包,则大部分实现都由工具包处理。
设置记住的设备-
在 Amazon Cognito 控制台中,选择 Manage user pools (管理用户池),然后选择您的用户池。
在左侧导航窗格中的一般设置下,选择设备。
对于 Do you want to remember your user's devices (您是否想要记住您用户的设备),请选择 Always (始终) 或 User Opt I (用户选择加入)。有关更多信息,请参阅使用 Amazon Cognito 跟踪和记住您用户池中的设备。
对于 Do you want to use a remembered device to suppress the second factor during multi-factor authentication (MFA) (您是否想要在多重身份验证 (MFA) 期间使用记住的设备阻止第二因素),请选择 Yes (是) 或 No (否)。有关更多信息,请参阅使用记住的设备来阻止多重身份验证 (MFA)。
注意:如果这些选项不出现,则 MFA 未启用。要设置 MFA,在左侧导航窗格中选择 MFA and verifications (MFA 和验证)。 选择 Save changes (保存更改)。
有关更多信息,请参阅指定用户池设备跟踪设置。
调用 SetUserMFAPreference在您的应用程序客户端代码中,调用 SetUserMFAPreference API,为您要使用的 MFA 方法将 MFA 首选项设置为 true。
调用 InitiateAuth在您的应用程序客户端代码中,调用 InitiateAuth API 来获取设备密钥。在此 API 请求中,确保包含以下请求参数:
AuthFlow。使用 USER_SRP_AUTH。 AuthParameters。包含身份验证参数 USERNAME、SRP_A 和 SECRET_HASH。注意:仅当您的应用程序客户端配置了客户端密钥时,才需要SECRET_HASH。
使用以下公式计算 SRP_A:
SRP_A = ga (mod N)
使用 AWS Amplify (JavaScript) GitHub 存储库上 AuthenticationHelper.js 中定义的 g。 令 a = 128 个随机字节有关更多信息,请参阅请求语法和您选择的 AWS 开发工具包的 API 参考。
为 MFA 质询调用 RespondToAuthChallenge应用程序客户端调用 InitiateAuth API 之后,您的 Amazon Cognito 用户池将根据您启用的 MFA 方法返回一系列 MFA 质询。
您的应用程序必须使用 RespondToAuthChallenge API 应答这些质询。例如,如果您在用户池中启用了 SMS 文本消息 MFA,则参数 ChallengeName 要包含值 SMS_MFA。有关更多信息,请参阅请求语法和您选择的 AWS 开发工具包的 API 参考。
存储设备密钥应答所有 MFA 质询后,Amazon Cognito 会在 NewDeviceMetadataType 字段中以 DeviceGroupKey 和唯一的 DeviceKey 进行响应。
如果您在浏览器中使用适用于 Android、iOS 或 JavaScript 的 AWS 移动开发工具包,则这些密钥将由应用程序自动移至设备的本地存储中。如果您使用的是其他 AWS 开发工具包,请确保为您的应用程序设计类似的密钥存储解决方案。
调用 ConfirmDevice对于 DeviceGroupKey 和 DeviceKey,使用安全远程密码 (SRP) 协议创建一个秘钥,该协议会生成一个 salt 和一个密码验证程序。通过包含以下请求参数的 ConfirmDevice API 调用将这些传递到 Amazon Cognito:
AccessToken。使用对于用户有效的访问令牌。 DeviceKey。用从 Amazon Cognito 返回的设备唯一密钥。 DeviceName。使用您给设备指定的名称。(AWS 移动软件开发工具包使用用户代理。) DeviceSecretVerifierConfig。包括 Salt(16 个随机字节,以 base64 编码)和 PasswordVerifier。对于 PasswordVerifier:使用以下公式:
PasswordVerifier = g(salt + FULL_PASSWORD) (mod N)
使用 AWS Amplify (JavaScript) GitHub 存储库上 AuthenticationHelper.js 中定义的 g。 令 FULL_PASSWORD = SHA256_HASH(DeviceGroupKey + username + ":" + RANDOM_PASSWORD) 令 RANDOM_PASSWORD = 40 个随机字节,以 base64 编码 使用 AWS Amplify (JavaScript) GitHub 存储库上 AuthenticationHelper.js 中定义的 N。有关更多信息,请参阅请求语法和您选择的 AWS 开发工具包的 API 参考。
(可选)调用 UpdateDeviceStatus在设置记住用户池中的设备时,如果选择 Always (始终),则可以跳过此步骤。如果您选择 User Opt In (用户选择加入),您必须包含 UpdateDeviceStatus API 调用。
注意:如果您使用 Amazon Cognito Identity SDK for JavaScript,则必须调用setDeviceStatusRemembered 或 setDeviceStatusNotRemembered。有关更多信息,请参阅 GitHub 上开发工具包 README 文件中的 使用情况。
当您为应用程序的用户提供记住其设备的选项时,请确认该设备在您的用户池中将作为“未记忆”来跟踪。 您必须询问用户是否要记住其设备,然后使用 UpdateDeviceStatus API 发送其选择。
注意:当需要选择加入时,用户必须选择加入才能记住其设备并阻止 MFA 质询。
使用设备密钥调用 InitiateAuth在您的应用程序客户端代码中,调用 InitiateAuth API 来验证记住的设备。在此调用中,在请求参数中包含设备密钥,如下所示:
AuthFlow。使用 USER_SRP_AUTH。 AuthParameters。包含身份验证参数 USERNAME、SRP_A 和 DEVICE_KEY。有关更多信息,请参阅请求语法和您选择的 AWS 开发工具包的 API 参考。
为 DEVICE_SRP_AUTH 调用 RespondToAuthChallenge应用程序客户端使用有效的设备密钥进行 InitiateAuth API 调用后,您的 Amazon Cognito 用户池将返回 DEVICE_SRP_AUTH 质询。要予以响应,调用 RespondToAuthChallenge API 并包含以下请求参数:
ChallengeName。使用 DEVICE_SRP_AUTH。 ClientId。使用有效的应用程序客户端 ID。 ChallengeResponses。在这些响应中包含 USERNAME、DEVICE_KEY 和 SRP_A。注意:对于 SRP_A,使用说明中前面提到的公式。
调用此 API 后,Amazon Cognito 将以另一个质询响应:DEVICE_PASSWORD_VERIFIER。在响应中,您还将获得 ChallengeParameters SECRET_BLOCK 和 SRP_B 的值,可供响应质询之用。
有关更多信息,请参阅请求语法和您选择的 AWS 开发工具包的 API 参考。
为 DEVICE_PASSWORD_VERIFIER 调用 RespondToAuthChallenge要响应 DEVICE_PASSWORD_VERIFIER 质询,调用 RespondToAuthChallenge API 并包含以下请求参数:
ChallengeName。使用 DEVICE_PASSWORD_VERIFIER。 ClientId。使用有效的应用程序客户端 ID。 ChallengeResponses。包含 USERNAME、PASSWORD_CLAIM_SECRET_BLOCK、TIMESTAMP、PASSWORD_CLAIM_SIGNATURE 和 DEVICE_KEY。定义质询响应,如下所示:
对于 PASSWORD_CLAIM_SECRET_BLOCK,使用 SECRET_BLOCK 的值。 对于 TIMESTAMP,包含当前时间。(例如,Tue Sep 25 00:09:40 UTC 2018。) 令 PASSWORD_CLAIM_SIGNATURE = SHA256_HMAC(K_USER, DeviceGroupKey + DeviceKey + PASSWORD_CLAIM_SECRET_BLOCK + TIMESTAMP),使用 base64 编码 令 K_USER = SHA256_HASH(S_USER) 令 S_USER = (SRP_B - k * gx)(a + ux) 令 x = SHA256_HASH(salt + FULL_PASSWORD) 令 u = SHA256_HASH(SRP_A + SRP_B) 令 k = SHA256_HASH(N + g) 从您的用户池获取 JSON Web 令牌成功响应上一个质询后,您的 Amazon Cognito 用户池在 AuthenticationResult 中返回 JSON Web 令牌:
{
"AuthenticationResult": {
"AccessToken": "...",
"ExpiresIn": 3600,
"IdToken": "...",
"RefreshToken": "...",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}