Search code examples
amazon-web-servicesamazon-cognitoaws-sdk-js

How do I list all users in my Cognito User Pool in my React application?


I have a CMS application which site editors can log into. I want to create a dashboard for the editors to be able to create and delete site users. Site user accounts will be maintained through a AWS Cognito User Pool, while site editors log in through their account with the CMS.

To begin with, I want to be able to list all users in a given user pool for the editors to view, so I'm following the SDK docs here, but it doesn't explain how to pass any credentials to the method. This is with v3 of the SDK, and any examples I can find that does something similar uses v2.

I get this far:

import { CognitoIdentityProviderClient, ListUsersCommand } from "@aws-sdk/client-cognito-identity-provider";

const client = new CognitoIdentityProviderClient({ region: "eu-west-2" });
const params = {};
const command = new ListUsersCommand({ UserPoolId: "My_User_Pool_Id" });

try {
    const data = await client.send(command);
    return this.setState({ users: data });
} catch (error) {
    console.error(error);
    return this.setState({ error: error });
} finally {
    this.setState({ loading: false });
}

But this gives me an error when I run the above code and render the component:

Error: Credential is missing
    at SignatureV4.credentialProvider (runtimeConfig.browser.js:15)
    at SignatureV4.<anonymous> (SignatureV4.js:169)
    at step (tslib.es6.js:100)
    at Object.next (tslib.es6.js:81)
    at tslib.es6.js:74
    at new Promise (<anonymous>)
    at __awaiter (tslib.es6.js:70)
    at SignatureV4.signRequest (SignatureV4.js:165)
    at SignatureV4.<anonymous> (SignatureV4.js:85)
    at step (tslib.es6.js:100)

I assume I need to create some credentials (through IAM?) for my dashboard to access the user pools, but I don't know where to create these or how to pass them to the SDK. Googling around this subject seemed to suggest I should make an unauthenticated Identity Pool and attached IAM permissions to that, then pass that pool's credentials to the SDK, but that gave me permissions errors too:

AccessDeniedException: User: [DashboardAdmin IdentityPool ARN] is not authorized to perform: cognito-idp:ListUsers on resource: [UserPool for Site Users ARN]

Solution

  • I eventually found the correct part of the v3 docs around getting and setting credentials.

    You get credentials by creating them through a new IAM user for your application, as described here.

    There are then multiple different ways you can add them to your app, as per this guide, depending on whether you're working on the server side or the client side. For example, hard-coding them on the server-side requires this change:

    const client = new CognitoIdentityProviderClient({ region: "eu-west-2" });
    

    change to

    const client = new CognitoIdentityProviderClient({
        region: "eu-west-2",
        credentials: {
            accessKeyId: process.env.YOUR_AWS_ACCESS_KEY_ID,
            secretAccessKey: process.env.YOUR_AWS_SECRET_ACCESS_KEY,
        },
    });
    

    Then, the error User is not authorized to perform: cognito-idp:ListUsers on resource is solved by adding a policy allowing cognito-idp:ListUsers to the IAM user you created above. This answer steered me in the correct direction for that.