Local cognito-idp
In one of the companies I worked for, we used cognito-idp as our identity
provider and have set up native cognito-idp and gateway integration for our
authorizer.
When using that integration, the gateway injects your user information into your
lambda event if auth is successful, otherwise returns 401.
When running your services locally, that introduces a couple of challenges. In theory we could work around that issue by using a gateway without an authorizer when testing locally, but that has a couple of problems:
- You are avoiding auth and potentially propagating risky bugs
- If you are doing something with the user from the lambda event, you have to comment out those parts
- ...
You could also connect to your cognito-idp for authorization, but then you run
into an issue with using multiple aws profiles during development.
- Using
devprofile for cognito - Using
localprofile for any other aws resource
Since cognito-idp is a paid feature for localstack,
we needed to find an alternative solution.
cognito-local is an open source
mock for cognito-idp. It follows the cognito-idp public api, although it
doesn't contain all of the features and there are some minor differences in the
api. It should allow you to set up your auth flows locally in most cases.
Setup
Run cognito-local as a docker container and attach a volume to it.
# docker-compose.yaml
services:
localcognito:
image: jagregory/cognito-local:latest
ports:
- "9229:9229"
volumes:
- ./localcognito-data:/app/.cognitoUsage
Start your cognito-local with docker compose up.
Add a local profile to work with cognito-local:
# config
[profile local]
region = us-east-1
output = json
endpoint_url = http://localhost:4566
services = local-services
[services local-services]
cognito_identity_provider =
endpoint_url = http://localhost:9229
# credentials
[local]
aws_access_key_id = test
aws_secret_access_key = test
Lets create a user pool:
aws cognito-idp create-user-pool \
--pool-name users \
--username-attributes "" \
--profile local \
--query 'UserPool.Id' \
--output text
This will print your user pool id, something like local_3gvkhgsA.
Afterwards, create an app client for that user pool:
aws cognito-idp create-user-pool-client \
--user-pool-id local_3gvkhgsA \
--client-name users-client \
--no-generate-secret \
--profile local \
--query 'UserPoolClient.ClientId' \
--output text
This will print your app client id, something like cxk4mo78phezi6bv8ixxsb04p.
And finally, create some users and set their initial passwords:
aws cognito-idp admin-create-user \
--user-pool-id local_3gvkhgsA \
--username user1 \
--user-attributes Name=email,Value="user1@mail.com" \
--message-action SUPPRESS \
--profile local
aws cognito-idp admin-set-user-password \
--user-pool-id local_3gvkhgsA \
--username user1 \
--password test \
--permanent \
--profile local
Now, you can obtain your tokens by running:
aws cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--client-id cxk4mo78phezi6bv8ixxsb04p \
--auth-parameters USERNAME=user1,PASSWORD=test \
--profile local
cognito-local enabled us to run all of our apis locally e2e without issues. In
one of the next blogs, I will show how to connect your gateway authorizer to
cognito-local.