How to get user attributes (username, email, etc.) using cognito identity id
Asked Answered
K

11

78

I have AWS Cognito Identity Pool that is configured with Cognito User Pool as an authentication provider.

Assume I have identity ID of an identity in Cognito Identity Pool (e.g. us-east-1:XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX) where this identity has a linked login to a user in Cognito User Pool.

Using identity ID, how can I get the linked user details (email, phone, username)?

Knout answered 22/6, 2016 at 9:28 Comment(0)
A
69

The ID Token that you exchange with Cognito federated identity service to get the identity id and credentials already has all user attributes. You do not need an extra call to any service.

enter image description here

It is a JWT token and you can use any library on the client to decode the values. You can read this guide for more information about the tokens vended by Cognito user pools.

Alternatively, you can also use the Access Token to call GetUser API which will return all the user information.

Ailis answered 22/6, 2016 at 21:32 Comment(9)
I am giving access to a user to invoke a single lambda function. When invoked, I can get context.identity.cognito_identity_id. And that's why I want to get user info using identitiy_id, Is there a way to get JWT token? Can I safely pass it to lambda function in the payload?Knout
Yes. Refer to this post for instructions on how to do that.Ailis
I tried GetUser API but it's giving me An error occurred (InvalidParameterException) when calling the GetUser operation: 1 validation error detected: Value at 'accessToken' failed to satisfy constraint: Member must satisfy regular expression pattern: [A-Za-z0-9-_=.]+Knout
@Knout GetUser API needs access token not idtoken, mey be this is the reson.Quiver
@ChetanMehta About Attributes in ID token - I can't get custom attributes - it not included in token claims =(Quiver
Found solution for custom attributes need to mark them as readable in application settings, and then they will be placed in claimsQuiver
Tell me please more about instructions how to get JWT token using identity id.Holy
I've got an accessToken from my alexa skill from a user linked with cognito. How exactly do we use it against GetUser API to get the cognito user information? I see the API but what's the endpoint I target?Lavella
Found it: GET https://<your-user-pool-domain>/oauth2/userInfo Authorization: Bearer <access_token>Lavella
S
45

Using REST API

AccessToken

Thought that this could be very helpful to someone as I've spent a lot of time trying to figure out how to get UserAttributes with only accessToken and region ( Similar to this but with REST API ( Without using aws-sdk )

You can get UserAttributes with accessToken using this HTTP request. ( GetUser )

Method: POST
Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
Content-Type: application/x-amz-json-1.1
Content-Length: 1162 // Access Token bytes length
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
Body: {"AccessToken":"ACCESS_TOKEN"}

And if the accessToken is valid, you should receive example response like the following

{
    "UserAttributes": [
        {
            "Name": "sub",
            "Value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
        },
        {
            "Name": "email_verified",
            "Value": "true"
        },
        {
            "Name": "name",
            "Value": "Jason"
        },
        {
            "Name": "phone_number_verified",
            "Value": "true"
        },
        {
            "Name": "phone_number",
            "Value": "+xxxxxxxxxxx"
        },
        {
            "Name": "email",
            "Value": "[email protected]"
        }
    ],
    "Username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
}
Servility answered 4/11, 2019 at 2:29 Comment(8)
I can't express how helpful this was to me!Rialto
Thanks! This is more awesome than AWS's freaking doc! But when I shoot to https://cognito-idp.{REGION}.amazonaws.com/ with all the params, it gives me "__type": "SerializationException" don't we each need to POST to our own URL endpoint? where exactly do we get the server URL it is not specified in any doc!!Fatuity
Sorry my bad, it's actually working with that target URL, just that AccessToken has to be specified in the body, not Header, I was giving it as auth-header... Thanks a lot! Although it seems like a hack because aws-lib's get user is buggy, it saved my day!Fatuity
Though this is better than amazon docs.. but i am still getting this error - Access Token does not have required scopesTeachin
@KunalValecha Make sure you are using "access" token but not "id" or "refresh" token. I suspect that your token's scope to be something else. You can go to jwt debugger section to test your token. Note that tokens are credentials.Servility
I was about to craft the request but realized all I need is already in the event variable received by Lambda #65546029Sagamore
@KunalValecha I had the same issue and needed to add the aws.cognito.signin.user.admin scope for it to work. See this answer for info: https://mcmap.net/q/266351/-what-does-the-aws-cognito-signin-user-admin-scope-mean-in-amazon-cognitoCrowd
Thanks for the hint! I wanted to use AWS sdk for JavaScript, so I used getUser( {AccessToken}).Antonetteantoni
L
4

AWS cognito-idp list-users has a filter option that allows you to filter based on attribute. 'sub' is the attribute that matches the identity id you are describing.

e.g. at the command line:

aws cognito-idp list-users --user-pool-id us-east-1_abcdFghjI --filter "sub=\":XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX\""

This also requires the user-pool-id, which I suspect you have. Additionally, I have no idea how this is implemented or how it performances when filtering a large number of users, but I take custom attributes not being usable in filters as a hint that there is some form of indexing behind the curtain.

Lenlena answered 30/3, 2019 at 22:22 Comment(1)
'sub' no longer matches identity id. While both have a similar format, the values are different.Shondrashone
J
1

I faced the similar issue and after too much of scratching i was not able to find the exact way of pulling out the details. My usecase was to get the details in android APP. After looking into their AWSMobile client API code. I found below and it is working from me.

Log.i(TAG, "User Details"+ AWSMobileClient.getInstance().getUserAttributes().toString());

Recommendation - Try use AWSMobileclient incase you are using it for Android Development as this is new library that is recommended for development.

Jejune answered 19/12, 2018 at 3:10 Comment(0)
A
1

Just struggled with this for a while, and the way I got the user name, using Java API is:

identityManager.login(this, new DefaultSignInResultHandler() {
        @Override
        public void onSuccess(Activity activity, IdentityProvider identityProvider) {
            ...               
            String userName = ((CognitoUserPoolsSignInProvider) identityProvider).getCognitoUserPool().getCurrentUser().getUserId();
Adila answered 31/12, 2019 at 2:54 Comment(2)
This great for getting the ID. But can you use getCurrentUser() to find the email attribute instead of ID?Dickey
Could you please guide, how to get the "ID token" from the provider object?Contraindicate
A
1

There is a listener we can initialize that will listen to changes in our authentication state and allow us to have access to the type of authentication event that happened and update the application state based on that data.

With Amplify, the Hub module allows us to do this pretty easily:

import { Hub } from 'aws-amplify';

Hub.listen('auth', (data) => {
    const {payload} = data;
    if (payload.event === 'signOut') {
       console.log('signOut');
    } else if (payload.event === 'signIn') {
       console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
    }
});

enter image description here

Arabella answered 31/3, 2021 at 9:57 Comment(0)
K
0

For those who are looking how to get the value of email parameter in Java programmatically

I assume you have already figured out how to get the needed / all users from the pool.

Say I have ListUsersResult with my all users and say I want to check the email value of the first user:

ListUsersResult allUsers = getAllUsers();
UserType userType = allUsers.getUsers().get(0);

First I can get user's all attributes:

List<AttributeType> attributes = userType.getAttributes();

Then loop through the attributes looking for the one we're interested in (our case email):

for (AttributeType att : attributes) {
      if (att.getName().equals("email")) {
        // do whatever you want


      }
    }

Remember that printing in to the console will most probably not work since it is sensitive data. But you can compare it like this:

att.getValue().equals("mymail@mail")

Kinross answered 22/2, 2022 at 15:52 Comment(0)
R
0

When you get the AccessToken and RefreshToken, you also get a IdToken (if not, maybe try adding scope in Cognito)

The Id Token has some of the information decoded and can be very helpful without adding and extra call to AWS!

Check you Id Token with an online tool as jwt.io and see if the Attribute you need is there...

Reservoir answered 11/8, 2023 at 20:9 Comment(0)
E
0

Below aws cli command will return user email from username (aka user sub, user id)

aws cognito-idp admin-get-user --user-pool-id [user_pool_id] --username [user_id] --region [region] --query "UserAttributes[?Name=='email'].Value" --output text --debug
Equestrienne answered 24/3 at 13:29 Comment(0)
B
-12

Use this piece of code

       GetDetailsHandler detailsHandler = new GetDetailsHandler() {
     @Override
     public void onSuccess(CognitoUserDetails cognitoUserDetails) {
        CognitoUserAttributes cognitoUserAttributes=cognitoUserDetails.getAttributes();
        stringStringHashMap=new HashMap<>();
        stringStringHashMap =cognitoUserAttributes.getAttributes();
         userNumber=stringStringHashMap.get("phone_number");
        e1.setText(userNumber);

        Log.d("Response"," Inside DEATILS HANDLER");
        // Store details in the AppHandler
        AppHelper.setUserDetails(cognitoUserDetails);
        // Trusted devices?
        handleTrustedDevice();
       // e1.setText(input.getText().toString());
         }

         @Override
          public void onFailure(Exception exception) {
        closeWaitDialog();
        showDialogMessage("Could not fetch user details!", AppHelper.formatException(exception), true);
        }
       };
     private void getDetails() {
    AppHelper.getPool().getUser(username).getDetailsInBackground(detailsHandler);
      }  
Brophy answered 1/8, 2018 at 5:7 Comment(1)
You can't just paste unexplained code in an unspecified language and expect that to be helpful.Gassy
R
-26
console.log('username is ' + cognitoUser.getUsername());
Rigsby answered 17/12, 2017 at 0:58 Comment(1)
Would you like to augment your code-only answer with some explanation of how it will solve OPs problem?Sholes

© 2022 - 2024 — McMap. All rights reserved.