Logo

dev-resources.site

for different kinds of informations.

How to add Amazon Cognito Auth to a Web App (part 4)

Published at
4/23/2023
Categories
serverlessframework
amazonwebservices
amazoncognito
serverless
Author
jamesmillerblog
Author
15 person written this
jamesmillerblog
open
How to add Amazon Cognito Auth to a Web App (part 4)

Looking at the NodeJS logic that is run in lambda functions to power the Back End of Amazon Cognito Authentication.

Intro

In my last post, I explained how Amazon Cognito is integrated into the Front End, to allow content to become visible to users that have gone through the Auth process as shown in the below demo ๐Ÿ‘‡

In this post, Iโ€™ll explain how this same process can be implemented in the Back End.

If you look at the right side of the above gif, you will see an open console log. Please note the โ€˜Hello World!! :Dโ€˜ message that appears in the logs once the user has successfully signed in.

This message is returned to users, that have logged into the Front End and then gone through the Auth process on the Back End.

Implementing Cognito Auth on the Back End

I have a Wrapper.js template that you can use to spin up an implementation of Cognito, here are some highlight files from that template:

serverless/serverless.common.yml

service: ${file(./../../../serverless.env.json):service_name}-${file(./../../../serverless.env.json):stage}

provider:
  environment: ${file(./../../../serverless.env.json)}
  name: aws
  region: ${file(./../../../serverless.env.json):region}
  runtime: nodejs12.x
  stage: ${file(./../../../serverless.env.json):stage}
  apiGateway: # Optional API Gateway global config
    restApiId: ${file(./../../../serverless.env.json):api_gateway_rest_api_id} # REST API resource ID. Default is generated by the framework
    restApiRootResourceId: ${file(./../../../serverless.env.json):api_gateway_root_resource_id} # Root resource ID, represent as / path
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:Query
            - dynamodb:Scan
            - dynamodb:GetItem
            - dynamodb:PutItem
            - dynamodb:UpdateItem
            - dynamodb:DeleteItem
          Resource: "*"
        - Effect: Allow
          Action:
            - "execute-api:ManageConnections"
          Resource:
            - "arn:aws:execute-api:*:*:**/@connections/*"

custom:
  apiAuthorizer:
    id : ${file(./../../../serverless.env.json):cognito_authorizer}
  serverless-offline:
    host: '0.0.0.0'
Enter fullscreen mode Exit fullscreen mode

Serverless Framework in WrapperJS is organised into HTTP and Websocket services, each service has its own yaml configuration.

Variables that are exported from Terraform (the cognito details) are passed to the above file, which the individual services can then reference.

These variables are:

  • restApiId : the ID of the API Gateway that Serverless Framework should deploy lambda end points to
  • restApiIdRootResourceId : the root path of that API Gateway, that all lambda endpoints will be added to
  • apiAuthorizer : an API Authorizer that was created by Terraform from the ARN of the Cognito User Pool

serverless/services/http/users/serverless.yml

service: ${file(./../../../serverless.common.yml):service}-${self:custom.service}
useDotenv: true

provider: ${self:custom.common.provider}

functions:
  - ${file(userData/lambda.yml)}

plugins:
  - serverless-offline

custom:
  service: users-service
  common: ${file(./../../../serverless.common.yml)}
  apiAuthorizer: ${self:custom.common.custom.apiAuthorizer.id}
  serverless-offline: ${self:custom.common.custom.serverless-offline}
Enter fullscreen mode Exit fullscreen mode

In lines 4 and 15 of the Users serviceโ€™s yaml (our demo service), you can see the configurations declared in the previous file being set in this service.

serverless/services/http/users/userData/lambda.yml

getUserData:
handler: userData/index.handler
events:
  - http:
      path: users/data
      method: get
      integration: lambda
      authorizer:
        type: COGNITO_USER_POOLS
        authorizerId: ${self:custom.apiAuthorizer}
      cors:
        origin: '*'
        headers: # <-- Specify allowed headers
          - Content-Type
          - Authorization
Enter fullscreen mode Exit fullscreen mode

The configuration for the users/data endpoint (our test endpoint) is configured to return data if the Front End provides the authorizer that has been defined in lines 8โ€“10.

serverless/services/http/users/userData/index.js

'use strict';

module.exports.handler = async(event, context, callback) => {
  const response = {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true
    },
    body: 'Hello World!! :D'
  };
  callback(null, response);
};
Enter fullscreen mode Exit fullscreen mode

Finally, this is the lambda that is executed when the end point has been called and the appropriate authorisation is provided.

The function returns a body of โ€˜Hello World!! :Dโ€˜.

Conclusion

So that is it, the end of the 4 part tutorial series!!!!

I hope this has been helpful for you in understanding how to use Amazon Cognito on the Back End for Lambda functions in Serverless Framework.

Feel free to use the template I created for Wrapper.js to spin this up and give it a go!!

In the meantime, go build cool stuff and have fun :D


serverlessframework Article's
30 articles in total
Favicon
Build a highly scalable Serverless CRUD Microservice with AWS Lambda and the Serverless Framework
Favicon
Building Scalable Event Processing with Fan-out Pattern using the Serverless Framework
Favicon
Importing CloudFormation Resources to help fix deployments to Production
Favicon
How to add Amazon Cognito Auth to a Web App (part 4)
Favicon
Setting up for Serverless Development with AWS
Favicon
Basic Integration Testing with Serverless Framework
Favicon
Building an API with Ruby and the Serverless Framework
Favicon
How to use multiple runtimes in a single serverless microservice
Favicon
ShreyTheCray Interview: Serverless Framework & Cloud Explained
Favicon
Introducing multi-service deployments via Serverless Framework Compose
Favicon
Simple Serverless Scheduler
Favicon
Serverless (FaaS) vs. Containers โ€” when to pick which?
Favicon
Provisioned Concurrency: What it is and how to use it with the Serverless Framework
Favicon
AWS Lambda Function URLs with Serverless Framework
Favicon
The ABCs of IAM: Managing permissions with Serverless
Favicon
AWS Lambda Destination Support
Favicon
Managing Stages and Environments in Serverless Framework
Favicon
Using API Gateway WebSockets with the Serverless Framework
Favicon
How to Create a REST API with Azure Functions and the Serverless Framework โ€” Part 1
Favicon
How to deploy multiple micro-services under one API domain with Serverless
Favicon
How to Test Serverless Applications
Favicon
DynamoDB On-Demand: When, why and how to use it in your serverless applications
Favicon
The definitive guide to using Terraform with the Serverless Framework
Favicon
Serverless Framework example for Golang and Lambda
Favicon
Using SQS with AWS Lambda and Serverless
Favicon
Container Image Support for AWS Lambda
Favicon
Major changes to serverless-dotenv-plugin
Favicon
Using dotenv with the Serverless Framework
Favicon
API Gateway WebSocket APIs with the Serverless Framework
Favicon
Takeaways from using AppSync

Featured ones: