简体   繁体   English

iOS - AWS Cognito - 检查用户是否已存在

[英]iOS - AWS Cognito - Check if user already exists

I want to allow a user to enter their email address/password in a field.我想允许用户在字段中输入他们的电子邮件地址/密码。 Upon continuing, I want to run a check to see if that user already exists.继续后,我想检查一下该用户是否已经存在。 If they do, log them in and continue with app, if they do not, move to account creation flow where they will be instructed to add name, phone number, etc.如果他们这样做,请登录并继续使用应用程序,如果他们不这样做,则转到帐户创建流程,在那里他们将被指示添加姓名、电话号码等。

I cannot for the life of me find documentation on how to log a user in using AWS Cognito.我一生都找不到有关如何使用 AWS Cognito 登录用户的文档。 I should be able to pass email/pass in a call and get a response back that says User Exists/User does not exist or whatever!我应该能够在电话中传递电子邮件/传递并得到回复,说用户存在/用户不存在或其他什么! Am I missing something here?我在这里错过了什么吗?

Any help would be greatly appreciated.任何帮助将不胜感激。 I've scoured the documentation..this is my last resort.我已经搜索了文档......这是我最后的手段。

In the current SDK, calling getUser on your AWSCognitoIdentityUserPool just constructs the in-memory user object.在当前的开发工具包中,在您的AWSCognitoIdentityUserPool上调用getUser只会构建内存中的用户对象。 To make the call over the network, you need to call the getSession method on the constructed user.要通过网络进行调用,您需要对构造的用户调用getSession方法。 Here's a Swift 3 method I wrote to check whether an email is available:这是我编写的用于检查电子邮件是否可用的 Swift 3 方法:

/// Check whether an email address is available.
///
/// - Parameters:
///   - email: Check whether this email is available.
///   - completion: Called on completion with parameter true if email is available, and false otherwise.
func checkEmail(_ email: String, completion: @escaping (Bool) -> Void) {
        let proposedUser = CognitoIdentityUserPoolManager.shared.pool.getUser(email)
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        proposedUser.getSession(email, password: "deadbeef", validationData: nil).continueWith(executor: AWSExecutor.mainThread(), block: { (awsTask) in
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            if let error = awsTask.error as? NSError {
                // Error implies login failed. Check reason for failure
                let exceptionString = error.userInfo["__type"] as! String
                if let exception = AWSConstants.ExceptionString(rawValue: exceptionString) {
                    switch exception {
                    case .notAuthorizedException, .resourceConflictException:
                        // Account with this email does exist.
                        completion(false)
                    default:
                        // Some other exception (e.g., UserNotFoundException). Allow user to proceed.
                        completion(true)
                    }
                } else {
                    // Some error we did not recognize. Optimistically allow user to proceed.
                    completion(true)
                }
            } else {
                // No error implies login worked (edge case where proposed email
                // is linked with an account which has password 'deadbeef').
                completion(false)
            }
            return nil
        })
    }

For reference, my ExceptionString enum looks like this:作为参考,我的ExceptionString枚举如下所示:

public enum ExceptionString: String {
    /// Thrown during sign-up when email is already taken.
    case aliasExistsException = "AliasExistsException"
    /// Thrown when a user is not authorized to access the requested resource.
    case notAuthorizedException = "NotAuthorizedException"
    /// Thrown when the requested resource (for example, a dataset or record) does not exist.
    case resourceNotFoundException = "ResourceNotFoundException"
    /// Thrown when a user tries to use a login which is already linked to another account.
    case resourceConflictException = "ResourceConflictException"
    /// Thrown for missing or bad input parameter(s).
    case invalidParameterException = "InvalidParameterException"
    /// Thrown during sign-up when username is taken.
    case usernameExistsException = "UsernameExistsException"
    /// Thrown when user has not confirmed his email address.
    case userNotConfirmedException = "UserNotConfirmedException"
    /// Thrown when specified user does not exist.
    case userNotFoundException = "UserNotFoundException"
}

Some clarification is in order.一些澄清是有序的。 Cognito has several parts. Cognito 有几个部分。 The part that does "Authentication" (which is what you are talking about) is called "Cognito User Pools".执行“身份验证”(这就是您所说的)的部分称为“Cognito 用户池”。 Not to be confused with Cognito Federated Identity Pools.不要与 Cognito 联合身份池混淆。

With User Pools you can create usernames and password combinations with attributes, and these can be used to authenticate and deliver a persistent, cross device, Cognito Federated identity identityId to a user (across multiple devices).使用用户池,您可以创建具有属性的用户名和密码组合,这些可用于对用户(跨多个设备)进行身份验证和提供持久的、跨设备的 Cognito Federated 身份 identityId。

Once logged in, the Federated Identity Pool is hooked to roles which can get your "Authorized" to use AWS services (like Dynamo DB etc).登录后,联合身份池与角色挂钩,这些角色可以让您“获得授权”使用 AWS 服务(如 Dynamo DB 等)。

It can be tricky to get all these parts working together and AWS has an online site called "Mobile Hub" that will build code for you and download an xcode project.让所有这些部分协同工作可能很棘手,AWS 有一个名为“Mobile Hub”的在线站点,可以为您构建代码并下载 xcode 项目。 This process configures the Federated Identity Pool and the User Pool correctly, and connects them all up to a set of example code.此过程正确配置了联合身份池和用户池,并将它们全部连接到一组示例代码。

Connecting the credentials provider to the user pool to the identity pool is a bit counterintuitive, but the AWSIdentityManager in the aws-mobilehub-helper-ios on github manages all that for you.将凭证提供程序连接到用户池和身份池有点违反直觉,但 github 上 aws-mobilehub-helper-ios 中的 AWSIdentityManager 会为您管理所有这些。 So I would recommend starting with mobile hub on the console.所以我建议从控制台上的移动集线器开始。

Cognito is a somewhat confusing system, here is a link to a brief powerpoint that hits the highlights of how it works (for people that can't understand the AWS docs (like me)). Cognito 是一个有点令人困惑的系统,这里是一个简短的 powerpoint的链接,该链接介绍了它的工作原理(对于无法理解 AWS 文档的人(如我))。

With that said, "how to check if a user already exists?"话虽如此,“如何检查用户是否已经存在?”

The most reasonable approach is to create the user (via signup), and get a reject if the name is in use, and suggest that your user try a different username.最合理的方法是创建用户(通过注册),如果名称正在使用,则拒绝,并建议您的用户尝试不同的用户名。 With respect to the email being in use, you will get that reject upon confirmation (signup sends confirmation id's by email and/or via text).对于正在使用的电子邮件,您将在确认后收到拒绝(注册通过电子邮件和/或文本发送确认 ID)。 This can be overridden to reclaim the email address, or you can do a test beforehand to see if the email is in use by attempting to log in and looking at the failure code.这可以被覆盖以回收电子邮件地址,或者您可以通过尝试登录并查看失败代码来预先测试以查看电子邮件是否正在使用。

you can fetch the user as the other answer suggests, however if you have established in user pools an alias for login (like email) you will find this problematic, because this just tells you if someone has the user name, not if someone is already using the email address, and you will get a reject later at confirmation time.您可以按照其他答案的建议获取用户,但是如果您在用户池中建立了登录别名(如电子邮件),您会发现这有问题,因为这只会告诉您是否有人拥有用户名,而不是是否已经有人使用电子邮件地址,稍后您将在确认时收到拒绝。

ListUsers is now a nice way to check for existing usernames. ListUsers现在是检查现有用户名的好方法。

https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html

You can also look for existing emails, phone numbers, and other default attributes.您还可以查找现有的电子邮件、电话号码和其他默认属性。

Here is a simple .NET example:这是一个简单的 .NET 示例:

    Dim userRequest = New ListUsersRequest With {
            .UserPoolId = "poolId",
            .Filter = "username = bob@email.com"
        }
    Dim response = amazonCognitoIdentityProviderClient.ListUsers(userRequest)
    Debug.WriteLine(response.Users.Count)

Check user name exists by providing the userName before doing login process. 在执行login过程之前,通过提供userName检查用户名是否存在。 If you get value for getUser method then the user exists, if you get nil or error then user doesn't exists. 如果获取getUser方法的值,则该用户存在;如果获取nilerror则该用户不存在。

    let pool = AWSCognitoIdentityUserPool(forKey: "UserPool")
    let user: AWSCognitoIdentityUser = pool.getUser("userName")

Thanks:) 谢谢:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM