Skip to content
This repository was archived by the owner on Aug 7, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions content/en/user-guide/aws/cognito/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,72 @@ Ensuring this match is crucial for the proper functioning of the authentication
{"access_token": "eyJ0eXAi…lKaHx44Q", "expires_in": 86400, "token_type": "Bearer", "refresh_token": "e3f08304", "id_token": "eyJ0eXAi…ADTXv5mA"}
```

### Client credentials grant

The client credentials grant is designed for machine-to-machine (M2M) communication.
The Client Credentials Grant allows the machine (client) to authenticate itself directly with the authorization server using its credentials, such as a client ID and client secret.
The client credentials grant allows for scope-based authorization from a non-interactive system to an API.
Your app can directly request client credentials from the token endpoint to receive an access token.

To request the token from the LocalStack URL, use the following endpoint: `://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token`.
For additional information on our endpoints, refer to our [Internal Endpoints](https://docs.localstack.cloud/references/internal-endpoints/) documentation.

If there are multiple user pools, LocalStack identifies the appropriate one by examining the `clientid` of the request.

To get started, follow the example below:

```sh
#Create client user pool with a client.
export client_id=$(awslocal cognito-idp create-user-pool-client --user-pool-id $pool_id --client-name test-client --generate-secret | jq -rc ".UserPoolClient.ClientId")

#Retrieve secret.
export client_secret=$(awslocal cognito-idp describe-user-pool-client --user-pool-id $pool_id --client-id $client_id | jq -r '.UserPoolClient.ClientSecret')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take into account that if the LocalStack user has setup LocalStack as a separate container to their system, they won't be able to get the variables exported here.

What we did was have a local.env file in which the variables were defined (e.g. user pool id). Then pass that to the LocalStack container in the Environment section. Then, in the app use that same local.env to have the same environment information in both containers.

When creating the pool and so on, it would be cool to remind people that you can setup the custom_id, instead of letting LocalStack generate it.


#Create resource server
awslocal cognito-idp create-resource-server \
--user-pool-id $pool_id \
--identifier "api-client-organizations" \
--name "Resource Server Name" \
--scopes '[{"ScopeName":"read","ScopeDescription":"Read access to Organizations"}]'

```

You can retrieve the token from your application using the specified endpoint: `http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token`.

```javascript
require('dotenv').config();
const axios = require('axios');

async function getAccessTokenWithSecret() {
const clientId = process.env.client_id;
const clientSecret = process.env.client_secret;
const scope = 'api-client-organizations/read';
const url = 'http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token';

const authHeader = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${authHeader}`
};

const payload = new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
scope: scope
});

try {
const response = await axios.post(url, payload, { headers });
console.log(response.data);
} catch (error) {
console.error('Error fetching access token:', error.response ? error.response.data : error.message);
}
}

getAccessTokenWithSecret();
```

Copy link

@usl-cto usl-cto Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it would be better to have a sample code in which the Cognito client is created in the Python code, from which you could extract the client ID and secret, and then do the token request. The sh would only need to create the pool.

I say this because that may be a more common scenario, normally you would create as many apps as M2M users are in your system.

## Serverless and Cognito

Furthermore, you have the option to combine Cognito and LocalStack seamlessly with the [Serverless framework](https://www.serverless.com/).
Expand Down
Loading