How to Integrate API Gateway with Cognito to Serve Authenticate Users

Configure API Gateway to Serve Content to Authenticated Users with AWS Cognito User Pool

Rushi Donga
Enlear Academy

--

Architecture

Let me explain which AWS Services have been used and for which purpose in the above Architecture.

  • API Gateway : Used to create an API and integrate with AWS Cognito and AWS Lambda.
  • Cognito : To Authenticate the user.
  • Lambda : To serve a fixed response to the AWS API Gateway.

Pre-requisites

  • Basic knowledge of AWS API Gateway, AWS Cognito, and AWS Lambda is required

NOTE : Make sure, you create all of the resources in the same Region.

1. Configuring AWS Cognito User Pool.

Go to AWS Management Console.

Here you will find the Amazon Cognito service under Security, Identity & Compliance section.

Click on Manage User Pool, on the home Page of AWS Cognito.

Now click on the button Create User Pool. Now there will be different Sections to configure User Pool.

Section 1: Configure sign-in

First, you need to choose Authentication Providers. In the Providers Type, there are two options

  • Cognito User Pool

If you want the user to sign in using their email address, Phone Number, or User Name. You can select one or multiple Attributes which will be prompted when the user sign-up.

NOTE — You will not be able to change the sign-in options once you have created the User Pool

  • Federated Identity Providers

If you want your user to sign in with social identity providers like Facebook, Google, Amazon, or Apple.

Section 2: Configure security requirements

Password Policy defines the length and the complexity of the password your user can set. Contains two options.

  • Cognito Defaults — For default password length and complexity.
  • Custom — If you want to define custom password length and complexity.

Multi-factor authentication for enforcing Multi-Factor Authentication MFA during the user sign-in process. Contains Three options.

  • Require MFA — Recommended to require MFA while the user sign in.
  • Optional MFA — Opts the user to choose whether to require MFA or not.
  • No MFA — Provisions the user to sign in with a Single Authentication Factor.

User account recovery configures how the user will recover their account in case the user forgets their password. For now, leave the configuration to default.

Section 3: Configure Self-service sign-up

This defines whether to display a sign-up link on the sign-in page in the hosted UI. When Enable self-registration checkbox is the disabled user will not be able to create a new user profile. In this case Federation or the Administrator, API needs to be used to create User Profiles.

Attribute verification and user account confirmation define how the user will verify their identity when they sign up. Select Cognito to automatically send messages to verify and confirm. Contains three options.

i. Send SMS to verify the phone number.

ii. Send Email to verify the email address.

iii. Send SMS message if the phone number is available, otherwise send an email message

Required attributes define which attributes will be required when a new user is created. You can select multiple options among the multiple options available. For now, we will go with email only.

Custom attributes allow you to define any custom attributes that a user will require when a new user is created.

Section 3: Configure message delivery which defines how to send a message to a new user to verify their identity. Contains two options.

i. Send Email with Amazon SES to send a message to the user using AWS SES.

ii. Send email with Cognito to send messages with AWS Cognito.

Section 4: Integrate your app

i. Give a name to your user Pool in User Pool Name i.e. test-userPool

ii. Hosted authentication pages allows you to use Cognito’s Hosted UI and OAuth 2.0 servers for sign-up and sign-in purpose.

iii. Domain allows you to configure a domain for your Hosted UI endpoint. Contains two options.

Use Cognito Domain allows you to define your custom prefix to use with Amazon-owned domain.

Need to use the prefix that is available

Use a custom domain to use your own custom domain.

Initial app client defines an app client in your user pool that has the permission to call unauthenticated API Operations. Contains three options

i. Public Client for native, Browser, or Mobile apps. In simple words, it allows you to make Cognito API requests from the user systems which are not trusted with the client secret.

ii. Confidential Client for server-side Applications.

iii. Other allows you to choose your custom App.

  • For now, we will stick to Public Client and give the client name as test-Client
  • Client secrets are used by the server-side component of the App to authorize the API requests.

If you are using JavaScript SDK in your mobile/web app, select Don’t generate a client secret, because client secrets are not supported by JavaScript SDK.

  • Allowed Callback URLs are the URLs, to which the users will be redirected after successful signup or sign in.

Advanced App client setting.

  • In Authentication Flows leave it to default or Check or Uncheck as per your requirement.
  • Set Refresh Token, Access Token, ID Token expiration as per your requirements. In simple words, AWS will provide these tokens to your application to access AWS Resources and these token are valid for the specified time interval.
  • Leave Identity Providers to default.
  • OAuth 2.0 Grant Types defines how Cognito will grant tokens to your application.

Remember to select Implicit grant, so that the client will get access token and ID token .

  • OpenID Connect scopes specify the attributes the app client can retrieve using the Access Token.
  • Allowed sign-out URLs are the URLs to which the user will be redirected once the user has signed out.
  • In Allowed sign-out URLs, leave it to default or can define your own Read and Write permission to the Attributes.

Section 6: Review the configuration and click on Create User Pool.

Now, since we have created User Pool, let’s create a Lambda Function which simply returns a “Hello World” when invoked.

2. Lambda Function

  • Go to the AWS Lambda Console and click on Create Function
  • Choose Author from Scratch and provide a name to the Lambda Function eg test-API-function.
  • Select the run time environment you want and click on Create Function.

On Clicking a Create Function button, an IAM Role will be created which will provide AWS Lambda permission to send Logs to AWS Cloudwatch.

3. API Gateway

Create a Resource

  • Create a new REST API named test-API and the endpoint Type as Regional.
  • In the Resources tab choose Actions Create Resource.
  • Create a resource named test-API-resource.

Create a Method

  • Now, in the Resources Tab, select the test-API-resource Resource, and click on Actions — Create Method.
  • Create a GET Method.
  • Choose Lambda Function as the Integration type.
  • Choose the region of the Lambda Function.

NOTE : It is recommended to have the Lambda Function and the API gateway in the same Region

  • Choose the Lambda Function we just created i.e. test-API-function and click on Save.

A dialog box will prompt, which says, by clicking OK Permission will be granted to the API Gateway to invoke the mentioned Lambda Function.

Create an Authorizer

Choose Authorizer from the Tab and click on Create new Authorizer.

  • Name the Authorizer i.e. test-Authorizer and choose Cognito as the type.
  • In Cognito User Pool choose the user pool we just created i.e. test-API.
  • Add “Authorization” as Token Source and leave Token Validation as Empty and click on Create button.

Here, Token Source is the key in the Header , which will be used to pass the Access Token with in the header.

Now, since we have created Authorizer, it’s time to integrate our Authorizer with the API.

  • Go to the Resources tab, select the GET method we just created and click on Method Request.
  • Refresh the Page once.
  • In Authorization, choose the Authorizer we just created i.e. test-Authorizer, and add email in OAuth Scopes.

Now, it’s time to deploy the API.

  • Navigate to the Resources tab, click on Actions and choose Deploy API.
  • Create a new stage with the name test. You can add Stage Description and Deployment Description if needed and click on the Deploy button.

Now that we have finished configuring our resources, It’s high time to test our resources.

Testing

We will be testing our APIs using Postman.

Step 1. Get the Access Token

  • Go to the AWS Cognito Console and select the User Pool we just created. i.e. test-API.
  • Navigate to the App Integration tab and select the App Client we just created i.e. test-Client. Over here, in the Hosted UI section, click on the button named View Hosted UI.
  • It will open a Link in a New Tab.
  • View the opened Link carefully, and change the response_type=code to response_type=token and click enter on the keyboard.

Changing the response type = token, will grant us access token and id token after a successful sign up or sign in.

  • Create a new Account or sign in, to an existing account.
  • After successful signup or sign-in, you will be redirected to another page. Now copy the URL and extract the access_token from the URL.

Step 2. Get the API

Navigate the AWS API Gateway Console and open the API we just created i.e. test-API.

  • Click on the Stages Tab and copy the Invoke URL.

Step 3. Open postman.com

Create a new account or log in to an existing account.

  • Click on My Workspace.
  • Modify the URL copied from the API Gateway console to the API as mentioned in the below Image.
  • Also, configure the Headers section as shown in the below image.

Mine looks like this.

  • Then click on the send button and will get the response as mentioned in the below image.
  • If someone tries to invoke the API with the Expired Token or Invalid Token or No Token, then they will get a response like

With this, you have successfully Configured and Tested API Gateway which serves content only to the Authenticated users in Cognito User Pool.

--

--

AWS Certified Solutions Architect. Presenting my learnings @AWS by translating them to a plain English. Writer @Enlear Academy | Writer @AWS in plain English