-
Notifications
You must be signed in to change notification settings - Fork 128
Cognito client crendetials flow #1528
Changes from 8 commits
603634b
e5f1693
d4deffa
4bf6f74
4d49609
f96c43a
21342dd
6c2f9f8
3351507
3ed93c9
9de479d
cd4583d
29b354f
a6c696f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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. | ||
| In contrast, the authorization code and implicit grants provide tokens to authenticated human users. | ||
| 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 LocalStack the correct URL is `http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token`. | ||
drauedo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| For additional information on our endpoints you can check our [Internal Endpoints](https://docs.localstack.cloud/references/internal-endpoints/) documentation. | ||
drauedo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| In case that there is more than one user pool, LocalStack detects the right one by inspecting the `clientId` of the requests. | ||
drauedo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Here is an example on how to set it up: | ||
drauedo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```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') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"}]' | ||
|
|
||
| ``` | ||
|
|
||
| Then you can retrieve the token from your application by using the mentioned endpoint: `http://cognito-idp.localhost.localstack.cloud:4566/_aws/cognito-idp/oauth2/token` endpoint. | ||
drauedo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```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(); | ||
| ``` | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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/). | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.