JAVA- AWS Cognito – 检查用户是否存在于 Cognito 用户池中

huangapple go评论70阅读模式
英文:

JAVA- AWS Cognito -Check if a user exists in Cognito User pool

问题

我想允许用户在一个字段中输入他们的用户名/密码。继续操作后,我想要运行一个检查,看看该用户是否已经存在于用户池中。如果是,就登录并继续使用应用;如果不是,则进入帐户创建流程,在该流程中,他们将被要求添加姓名、电话号码、电子邮件等。

我找不到关于如何使用AWS Cognito登录用户的文档。我应该能够在调用中传递用户名/密码,并得到一个回应,显示用户存在/用户不存在或其他内容!我是不是漏掉了什么重要的信息?

非常感谢任何帮助。我已经仔细查阅了文档...

英文:

I want to allow a user to enter their username/password in a field. Upon continuing, I want to run a check to see if that user already exists in the user pool. 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, email etc.

I cannot find documentation on how to log a user in using AWS Cognito. I should be able to pass username/passcode 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...

答案1

得分: 2

要检查用户是否存在,你只需要用户名。

因此,针对你的情况,在用户输入用户名和密码后触发下面的myMethod()方法。这将会:

  1. 检查用户名是否已经存在用户中。
  2. 如果用户名存在,执行登录操作。
  3. 如果用户名不存在,创建账户。
/**
* 假设你在用户输入用户名和密码时调用这个方法
* @param context 上下文
* @param identityProvider Cognito客户端
* @param username 用户输入的用户名
* @param password 用户输入的密码
* @return
*/
private void myMethod(Context context, AWSCognitoIdentityProvider identityProvider, String username, String password) {
    
    boolean userExists = userExists(context, identityProvider, username);
    
    if(userExists) {
        // 使用提供的密码执行登录操作
    } else {
        // 创建账户
    }
}


/**
* @param context 上下文
* @param identityProvider Cognito客户端
* @param username 用户输入的用户名
* @return 如果用户名已经被使用,返回true;否则返回false
*/
private boolean userExists(Context context, AWSCognitoIdentityProvider identityProvider, String username) {
    LambdaLogger logger = context.getLogger();

    try {
        AdminGetUserRequest getUserRequest = new AdminGetUserRequest();
        getUserRequest.setUserPoolId("cognitoPoolId");
        getUserRequest.setUsername(username);

        AdminGetUserResult getUserResult = identityProvider.adminGetUser(getUserRequest);

        return true;
    } catch (UserNotFoundException userNotFoundException) {
        logger.log("UserNotFoundException! " + userNotFoundException.toString());
        return false;
    } catch (Exception e) {
        return false;
    }
}
英文:

To check if the user exists or not, all you need is username.

So for your scenario, trigger the myMethod() below after user enters username and password. That will

  1. Check if the username is already in user
  2. If username exists, perform sign in
  3. If username does not exists, create account

/**
* let's say you call this method when user enters username and password
* @param context context
* @param identityProvider cognito client
* @param username user entered username
* @param password user entered password
* @return
*/
private void myMethod(Context context, AWSCognitoIdentityProvider identityProvider, String username, String password) {
    
    boolean userExists = userExists(context, identityProvider, username);
    
    if(userExists) {
        // perform sign in with provided password
    } else {
        // create account
    }
}


/**
* @param context context
* @param identityProvider cognito client
* @param username user entered username
* @return true if username is already in use, false otherwise
*/
private boolean userExists(Context context, AWSCognitoIdentityProvider identityProvider, String username) {
    LambdaLogger logger = context.getLogger();

    try {
        AdminGetUserRequest getUserRequest = new AdminGetUserRequest();
        getUserRequest.setUserPoolId("cognitoPoolId");
        getUserRequest.setUsername(username);

        AdminGetUserResult getUserResult = identityProvider.adminGetUser(getUserRequest);

        return true;
    } catch (UserNotFoundException userNotFoundException) {
        logger.log("UserNotFoundException! " + userNotFoundException.toString());
        return false;
    } catch (Exception e) {
        return false;
    }
}

答案2

得分: 0

以下是翻译的内容:

不必每次都对 Cognito 用户池进行完整扫描,我会利用 Cognito 触发事件的能力。对于您的用例,Cognito 可以运行一个 Lambda 函数。您对「迁移用户」触发器感兴趣。基本上的情况是,当用户尝试通过 Cognito 登录您的系统用户不存在于池中时,将触发一个触发器,让您登录用户并将其迁移到 Cognito。

传入的数据如下:

{
    "version": "1",
    "triggerSource": "UserMigration_Authentication",
    "region": "us-west-2",
    "userPoolId": "us-west-2_abcdef",
    "userName": "theusername@example.com",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-unknown-unknown",
        "clientId": "yourclientid"
    },
    "request": {
        "password": "theuserpassword",
        "validationData": null,
        "userAttributes": null
    },
    "response": {
        "userAttributes": null,
        "forceAliasCreation": null,
        "finalUserStatus": null,
        "messageAction": null,
        "desiredDeliveryMediums": null
    }
}

您的 Lambda 将消耗这些数据,并最终获取用户名和密码,然后确定其是否有效。如果有效,您将在 response.userAttributes 字段中返回信息,以及是否要发送 Cognito 欢迎电子邮件 (messageAction) 和其他一些值。例如,您可以返回:

{
    "version": "1",
    "triggerSource": "UserMigration_Authentication",
    "region": "us-west-2",
    "userPoolId": "us-west-2_abcdef",
    "userName": "theusername@example.com",
    "callerContext": {
        "awsSdkVersion": "aws-sdk-unknown-unknown",
        "clientId": "yourclientid"
    },
    "request": {
        "password": "theuserpassword",
        "validationData": null,
        "userAttributes": null
    },
    "response": {
        "userAttributes": {
            "email": "theusername@example.com",
            "email_verified": "true"
        },
        "forceAliasCreation": null,
        "finalUserStatus": "CONFIRMED",
        "messageAction": "SUPPRESS",
        "desiredDeliveryMediums": null
    }
}

您的 Lambda 在 Java 中的示例代码如下:

public class MigrateUserLambda implements RequestStreamHandler {

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        LambdaLogger logger = context.getLogger();

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(inputStream);

        logger.log("input is " + objectMapper.writeValueAsString(rootNode));

        String email = rootNode.path("email").asText();
        String password = rootNode.path("request").path("password").asText();

        // 验证 MySQL 中的用户名和密码。如果通过...

        String triggerSource = rootNode.path("triggerSource").asText();

        if (triggerSource.equals("UserMigration_Authentication")) {
            JsonNode responseNode = rootNode.path("response");
            if (responseNode != null) {
                ((ObjectNode) responseNode).with("userAttributes").put("username", "theusername@example.com");
                ((ObjectNode) responseNode).with("userAttributes").put("email_verified", "true");
                ((ObjectNode) responseNode).put("messageAction", "SUPPRESS");
                ((ObjectNode) responseNode).put("finalUserStatus", "CONFIRMED");
            }
        }

        String output = objectMapper.writeValueAsString(rootNode);

        OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
        writer.write(output);
        logger.log("sending back " + output);

        writer.close();
    }
}
英文:

Instead of having to do a full scan of your Cognito user pool every time, I'd use the ability of Cognito to trigger an event. For your use case Cognito can run a Lambda. You're interested in the <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-migrate-user.html">Migrate User</a> trigger. Basically what happens is that when the user tries to log into your system through Cognito and the user doesn't exist in the pool, a trigger is fired to let you log the user in and migrate them to Cognito.

The data coming in looks like:

{
&quot;version&quot;: &quot;1&quot;,
&quot;triggerSource&quot;: &quot;UserMigration_Authentication&quot;,
&quot;region&quot;: &quot;us-west-2&quot;,
&quot;userPoolId&quot;: &quot;us-west-2_abcdef&quot;,
&quot;userName&quot;: &quot;theusername@example.com&quot;,
&quot;callerContext&quot;: {
&quot;awsSdkVersion&quot;: &quot;aws-sdk-unknown-unknown&quot;,
&quot;clientId&quot;: &quot;yourclientid&quot;
},
&quot;request&quot;: {
&quot;password&quot;: &quot;theuserpassword&quot;,
&quot;validationData&quot;: null,
&quot;userAttributes&quot;: null
},
&quot;response&quot;: {
&quot;userAttributes&quot;: null,
&quot;forceAliasCreation&quot;: null,
&quot;finalUserStatus&quot;: null,
&quot;messageAction&quot;: null,
&quot;desiredDeliveryMediums&quot;: null
}
}

Your Lambda will consume this and ultimately take the username and password and determine if it is valid. If it is, you will pass back information in the response.userAttributes field along with things like if you want to send a Cognito welcome email (messageAction) and some other values. For example, you may send back:

{
&quot;version&quot;: &quot;1&quot;,
&quot;triggerSource&quot;: &quot;UserMigration_Authentication&quot;,
&quot;region&quot;: &quot;us-west-2&quot;,
&quot;userPoolId&quot;: &quot;us-west-2_abcdef&quot;,
&quot;userName&quot;: &quot;theusername@example.com&quot;,
&quot;callerContext&quot;: {
&quot;awsSdkVersion&quot;: &quot;aws-sdk-unknown-unknown&quot;,
&quot;clientId&quot;: &quot;yourclientid&quot;
},
&quot;request&quot;: {
&quot;password&quot;: &quot;theuserpassword&quot;,
&quot;validationData&quot;: null,
&quot;userAttributes&quot;: null
},
&quot;response&quot;: {
&quot;userAttributes&quot;: { &quot;email&quot;:&quot;theusername@example.com&quot;,
&quot;email_verified&quot;: &quot;true&quot; }
&quot;forceAliasCreation&quot;: null,
&quot;finalUserStatus&quot;: &quot;CONFIRMED&quot;,
&quot;messageAction&quot;: &quot;SUPPRESS&quot;,
&quot;desiredDeliveryMediums&quot;: null
}
}

Your Lambda will look something like this in Java:

public class MigrateUserLambda implements RequestStreamHandler {
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
LambdaLogger logger = context.getLogger();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(inputStream);
logger.log(&quot;input is &quot; + objectMapper.writeValueAsString(rootNode));
String email = rootNode.path(&quot;email&quot;).asText();
String password = rootNode.path(&quot;request&quot;).path(&quot;password&quot;).asText();
// verify user name and password in MySQL.  If ok...
String triggerSource = rootNode.path(&quot;triggerSource&quot;).asText();
if( triggerSource.equals(&quot;UserMigration_Authentication&quot;)) {
JsonNode responseNode = rootNode.path(&quot;response&quot;);
if (responseNode != null) {
((ObjectNode) responseNode).with(&quot;userAttributes&quot;).put(&quot;username&quot;, &quot;theusername@example.com&quot; );
((ObjectNode) responseNode).with(&quot;userAttributes&quot;).put(&quot;email_verified&quot;, &quot;true&quot; );
((ObjectNode) responseNode).put(&quot;messageAction&quot;, &quot;SUPPRESS&quot;);
((ObjectNode) responseNode).put(&quot;finalUserStatus&quot;, &quot;CONFIRMED&quot;);
}
}
String output = objectMapper.writeValueAsString(rootNode);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
writer.write(output);
logger.log(&quot;sending back &quot; + output);
writer.close();
}
}

答案3

得分: -1

public static void list() {
    AwsBasicCredentials awsCreds = AwsBasicCredentials.create(AWS_KEY,
            AWS_SECRET);

    CognitoIdentityProviderClient identityProviderClient =
            CognitoIdentityProviderClient.builder()
                    .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                    .region(Region.of(REGION))
                    .build();

    final ListUsersRequest listUsersRequest = ListUsersRequest.builder()
            .userPoolId(POOL_ID)
            .build();

    ListUsersResponse result = identityProviderClient.listUsers(listUsersRequest);

    System.out.println("Has users:" + result.hasUsers());
    result.users().stream().map(u->u.username()).forEach(System.out::println);
}
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>aws-core</artifactId>
  <version>2.13.57</version>
</dependency>

<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>cognitoidentityprovider</artifactId>
  <version>2.13.57</version>
</dependency>

这里 是一个从Java登录用户的代码示例。


<details>
<summary>英文:</summary>
To list users you can use AWS Java SDK:
public static void list() {
AwsBasicCredentials awsCreds = AwsBasicCredentials.create(AWS_KEY,
AWS_SECRET);
CognitoIdentityProviderClient identityProviderClient =
CognitoIdentityProviderClient.builder()
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.region(Region.of(REGION))
.build();
final ListUsersRequest listUsersRequest = ListUsersRequest.builder()
.userPoolId(POOL_ID)
.build();
ListUsersResponse result = identityProviderClient.listUsers(listUsersRequest);
System.out.println(&quot;Has users:&quot;+result.hasUsers());
result.users().stream().map(u-&gt;u.username()).forEach(System.out::println);
}
it requires next dependecies (please use latest versions):
&lt;dependency&gt;
&lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
&lt;artifactId&gt;aws-core&lt;/artifactId&gt;
&lt;version&gt;2.13.57&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;software.amazon.awssdk&lt;/groupId&gt;
&lt;artifactId&gt;cognitoidentityprovider&lt;/artifactId&gt;
&lt;version&gt;2.13.57&lt;/version&gt;
&lt;/dependency&gt;
[Here](https://stackoverflow.com/questions/63929294/how-to-configure-aws-user-cognito-authentication-flow-for-generating-identity-to) is a code sample of how to login user from Java. 
</details>

huangapple
  • 本文由 发表于 2020年10月22日 02:15:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64469431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定