如何使用我的 Amazon Cognito 用户群体中记住的设备?
我想跟踪 Amazon Cognito 用户群体中的用户用于登录我的应用程序的设备。
简短描述
Amazon Cognito 可以跟踪和记忆用户群体中的用户用于登录的设备。通过设备记忆功能,您可以设置登录限制,例如限制从单台设备登录。您还可以让用户在同一台设备上跳过重复登录。有关更多信息,请参阅指定用户群体设备跟踪设置。
**注意:**您必须使用 USER_SRP_AUTH 身份验证流才能使用设备跟踪功能。要使用记住的设备取代多重身份验证(MFA),还必须为用户群体启用 MFA。
记住设备流程由两部分组成:
- 确认新设备: 从设备启动身份验证,然后使用 Amazon Cognito 进行确认,获取唯一的设备标识符。
- 验证已确认的设备: 从已确认的设备启动身份验证,以便在后续登录尝试时跳过 MFA 步骤。
解决方法
**注意:**这些说明描述了在您的应用程序客户端代码中进行的 Amazon Cognito API 调用。如果您使用客户端 SDK,例如 AWS Mobile SDK,则该 SDK 会处理大部分实施。
设置记住的设备
- 在 Amazon Cognito 控制台中,选择管理用户群体,然后选择您的用户群体。
- 在导航窗格的常规设置下,选择设备。
- 在是否要记住用户的设备中,选择始终或用户选择加入。有关更多信息,请参阅使用 Amazon Cognito 跟踪和记住您用户群体中的设备。
- 对于您是否想要在多重身份验证(MFA)期间使用记住的设备阻止第二因素,请选择是或否。有关更多信息,请参阅使用记住的设备来阻止多重身份验证(MFA)。
**注意:**如果未显示这些选项,则表示未激活 MFA。要设置 MFA,请在导航窗格中选择 MFA 和验证。 - 选择保存更改。
调用 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)
- 按照 AuthenticationHelper.js 中的定义使用 g。有关 g 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js。
- 假设 a = 128 个随机字节
有关更多信息,请参阅请求语法和所选 AWS SDK 的 API 参考。
为 MFA 质询调用 RespondToAuthChallenge
在您的应用程序客户端调用 InitiateAuth API 后,您的 Amazon Cognito 用户群体会返回一组 MFA 质询。MFA 质询基于您激活的 MFA 方法。
您的应用程序必须使用 RespondToAuthChallenge API 来应答这些质询。例如,如果您在用户群体中激活了 SMS 短信 MFA,则在参数中加入值为 SMS_MFA 的 ChallengeName。有关更多信息,请参阅请求语法和所选 AWS SDK 的 API 参考。
存储设备密钥
应答所有 MFA 质询后,Amazon Cognito 会在 NewDeviceMetadataType 字段中以 DeviceGroupKey 和唯一的 DeviceKey 进行响应。
您在浏览器中使用适用于 Android、iOS 或 JavaScript 的 AWS Mobile SDK 时,应用程序会将这些密钥自动移至设备的本地存储空间。如果您使用其他 AWS SDK,请务必为您的应用程序设计类似的密钥存储解决方案。
调用 ConfirmDevice
通过 DeviceGroupKey 和 DeviceKey,使用安全远程密码(SRP)协议创建密钥。这会生成一个 salt 验证器和一个密码验证器。在包含以下请求参数的 ConfirmDevice API 调用中将其传递给 Amazon Cognito:
- **AccessToken:**为用户使用有效的访问令牌。
- **DeviceKey:**使用从 Amazon Cognito 返回的设备唯一密钥。
- DeviceName:使用您为设备提供的名称。(AWS Mobile SDK 使用用户代理。)
- **DeviceSecretVerifierConfig:**包括 Salt(16 个随机字节,Base64 编码)和 PasswordVerifier。
对于 PasswordVerifier,请使用以下公式:
PasswordVerifier = g( SHA256_HASH(salt + FULL_PASSWORD) ) (mod N)
- 按照 AuthenticationHelper.js 中的定义使用 g。有关 g 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js。
- 假设 FULL_PASSWORD = SHA256_HASH(DeviceGroupKey + username + ":" + RANDOM_PASSWORD)
- 假设 RANDOM_PASSWORD = 40 个随机字节,base64 编码
- 按照 AuthenticationHelper.js 中的定义使用 N。有关 N 的定义,请参阅 GitHub 网站上的 AuthenticationHelper.js。
有关更多信息,请参阅请求语法和所选 AWS SDK 的 API 参考。
(可选)调用 UpdateDeviceStatus
在用户群体中设置记住的设备时,如果选择始终,则可以跳过此步骤。如果您选择用户选择加入,则必须包含 UpdateDeviceStatus API 调用。
**注意:**如果您使用适用于 JavaScript 的 Amazon Cognito Identity SDK,则必须改为调用 setDeviceStatusRemembered 或 setDeviceStatusNotRemembered。有关如何使用适用于 JavaScript 的 Amazon Cognito Identity SDK 的信息,请参阅 GitHub 网站上的用法。
您让应用程序的用户可以选择是否记住设备时,您的用户群体中的设备确认会被记录为“未记住”。 您必须询问用户是否想记住设备,然后使用 UpdateDeviceStatus API 发送他们的输入。
**注意:**需要选择加入时,用户必须先选择加入,然后才能记住设备并禁止 MFA 问题。
使用设备密钥调用 InitiateAuth
在应用程序客户端的代码中,调用 InitiateAuth API 来验证记住的设备。在此调用中,将设备密钥包含在请求参数中,如下所示:
- **AuthFlow:**使用 USER_SRP_AUTH。
- **AuthParameters:**包括身份验证参数 USERNAME、SRP_A 和 DEVICE_KEY。
有关更多信息,请参阅请求语法和所选 AWS SDK 的 API 参考。
为 DEVICE_SRP_AUTH 调用 RespondToAuthChallenge
在您的应用程序客户端使用有效的设备密钥进行 InitiateAuth API 调用后,您的 Amazon Cognito 用户群体将返回 PASSWORD_VERIFIER 质询。您必须在质询响应中包含 DEVICE_KEY。然后,您将收到 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 的值。您需要 SECRET_BLOCK 和 SRP_B 值来响应质询。
有关更多信息,请参阅请求语法和 所选 AWS SDK 的 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) (mod N) ] ] )(a + ux) ](mod N)
- 假设 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": {} }
相关信息
GitHub 网站上的 CognitoUser.js
相关内容
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前