Cognito + API Gateway + Node.js
What is Amazon Cognito?
Amazon
Cognito offers authentication, authorization, and user management for web and mobile apps. You can login with your username and password or
use third-party services like Facebook, Google, Amazon, etc.
Cognito provides two major components:
Cognito user pool
User pool provides sign-up and sign-in options for users. The user can be created either by themselves or by the Administrator.
Cognito identity pool
By using Federated Identities, you can sign in through social identity providers such as Amazon, Facebook, Google, etc. But it will have limited permissions to access other AWS services. By using Identity pool we can grant permission for the user to access AWS services.
This tutorial consists of three sections. The first section will
focus on how to set up the Cognito user pool,
In the second section, we can focus on
how the user can sign-up, sign-in and confirm the verification code provided by Cognito
by using node js application.
In the last section, we can focus on how to authenticate your API by using the Cognito user pool with AWS API gateway.
How to create Cognito User Pool?
Select Cognito service from `Security, Identity & compliance` menu.
You will be able to see the following screen:

Click on ‘Manage User Pools’ and click on ‘Create a user pool’, this will take you to the below page:

Either you can go with the default settings or you can
customize the settings. We will take you through the ‘Step through Settings’.
Enter
the ‘Pool name’ and click on the ‘Step through settings’.
Above screen, you can select what information is required for
the user when they sign-up/sign-in. Default ‘username’ option will be selected. You
can select ‘Email address or phone number' as well.
If you select username you can also select the optional
attributes below the username section. In the next section you can select what attributes are required for the
signup process.
In this section you can customize your password rules. Also
you can configure who can create the user (either administrator can create
users or user can create themselves).
Here you can configure the MFA authentication if needed.
This will enable one more layer of security rather than just using the user
name and password. You can configure the recovery process in this section.
You can customize how your user will get the email message by changing the template.
Here you can set the option to save the user’s device
Here you need to create an app client. This is the client
our Node.js application will be interacting with. Also, you need to click on the `Create app Client` option to create the client.
Here you can customize your workflow with triggers.
Here you can review your configuration and make the
necessary changes. Once you hit the ‘Create pool’ button it will create the
user pool.
You need Pool Id and Client id to interact with Cognito pool
from your Node.js server. You can see the pool id highlighted above. To get the app
client id, click on the app clients, see the image below:

Create Node server
This section will focus on creating the Node.js server and how Node application will interact with Cognito pool. You can customize the code based on your folder structure.
1. Create a folder for your project and install the following packages:
npm install express --save
npm install nodemon --save -dev
npm install body-parser --save
npm install amazon-cognito-identity-js --save
npm isntall node-fetch --save
2. Create app.js
const express = require("express")
const bodyParser = require("body-parser")
const app = express()
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json({limit:"10mb"}))
app.use('/api', require("./route"));
module.exports = app
3. Create index.js
const app = require('./app')
const config = require("./config")
app.listen(config.http.port)
console.info(`Service listens on port ${config.http.port}`)
4. Create a config file and set the user pool id and client id
module.exports = {
http: {
port: 3000
},
cognito: {
userPoolId: "ap-south-1_X8p5YNzu5",
clientId: "2kvvjb3fvtbp2pv9lfr7p1umvn"
}
}
4. Now we need to implement three end points (Sign-up, confirm verification code, sign-in). Create AuthController.js
const AuthService = require("./AuthService")
const objAuthService = new AuthService()
class AuthController {
async signUp(req, res) {
const userData = req.body
try {
const result = await objAuthService.signUp(userData)
res.send(result)
}
catch (err) {
res.send(err)
}
}
async confirmUser(req, res) {
const userName = req.body.username
const verificationCode = req.body.verificationcode
try {
const result = await objAuthService.confirmUser(userName, verificationCode)
res.send(result)
}
catch (err) {
console.log(err)
res.status(500).send(err)
}
}
async signIn(req, res) {
const userName = req.body.username
const password = req.body.password
try {
const result = await objAuthService.signIn(userName, password)
res.send(result)
}
catch (err) {
res.status(500).send(err)
}
}
}
module.exports = AuthController
module.exports = AuthController;
5. Create AuthService.js
const config = require('./config')
const AmazonCognitoIdentity = require('amazon-cognito-identity-js')
global.fetch = require('node-fetch')
class AuthService {
constructor() {
const poolData = {
UserPoolId: config.cognito.userPoolId,
ClientId: config.cognito.clientId
}
//const poolRegion = config.cognito.region
this.userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData)
}
async signUp(userData) {
return await new Promise((resolve, reject) => {
const name = userData.name
const email = userData.email
const password = userData.password
const username = userData.username
const userAttributes = []
userAttributes.push(new AmazonCognitoIdentity.CognitoUserAttribute(
{
Name: "email",
Value: email
}
))
userAttributes.push(new AmazonCognitoIdentity.CognitoUserAttribute(
{
Name: "name",
Value: name
}
))
this.userPool.signUp(username, password, userAttributes, null,
(err, result) => {
if (err) {
reject(err)
} else {
var cognitoUser = result.user
resolve(cognitoUser)
}
})
})
}
async confirmUser(username, verificationCode) {
return await new Promise((resolve, reject) => {
const userData = {
Username: username,
Pool: this.userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData)
cognitoUser.confirmRegistration(verificationCode, true,
(err, result) => {
if (err) {
reject(err)
}
else {
resolve(result)
}
})
})
}
async signIn(username, password) {
return await new Promise((resolve, reject) => {
const authenticationDetails = new AmazonCognitoIdentity
.AuthenticationDetails({ UserName: username,
Password: password })
const userData = {
Username: username,
Pool: this.userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData)
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
const accessToken = result.getIdToken().getJwtToken()
resolve(accessToken)
},
onFailure: (err) => {
reject(err)
}
})
})
}
}
module.exports = AuthService
6. Create route.js
const express = require("express")
const AuthController = require("./AuthController")
const router = express.Router()
const objAuthController = new AuthController()
router.post("/signup", objAuthController.signUp)
router.post("/confirm", objAuthController.confirmUser)
router.post("/signin", objAuthController.signIn)
module.exports = router;
7. Once the above steps are done, go to the command prompt and run the node server.
8. Hit the following APIs
1. Sign up (It will create the user in Cognito pool)
This request will create the user in Cognito pool. Cognito will send an email with verification code. We need to verify the verification code with the following API.
2. Confirm user (Verify the code)
"verificationcode":"" //you must have received the verification code in your email id
Cognito will return the id token which will be used to authenticate your APIs.
Configure API Gateway
1. Click on the `Authorizers` menu from your API and `Create New Authorizer`
2. Input the name, select type as 'cognito', select the user pool from the drop down and set the token source. See the image below:
3. Set up the Authorizer in your API resource - Go to Resources - > Select your API -> Method Request -> select Cognito Authorizer from the drop down (need to refresh the page, sometimes it wont be available in the dropdown box)
4. Deploy the API
5. Call the API from post man
Hope this helps. Thank you !!
No comments:
Post a Comment