User authentication is a critical part of web and mobile applications. Instead of managing authentication manually, AWS provides Cognito, which allows seamless user sign-up, login, and token-based authentication.
In this tutorial, weβll build a fully serverless authentication system using:
β
AWS Lambda - Serverless compute for API functions
β
Amazon API Gateway - Expose API endpoints
β
AWS Cognito - User authentication and authorization
β
DynamoDB - Store user data
β
Serverless Framework - Automate deployment
By the end of this tutorial, youβll have a working authentication system with JWT authentication, CRUD operations, and secure API access. π
π Project Overview
πΉ Features
β User Sign-up & Login using AWS Cognito
β JWT Authentication for API security
β User Data Management (CRUD) with DynamoDB
β Serverless API Deployment with AWS Lambda & API Gateway
β Secure IAM Roles for fine-grained access control
π Architecture Diagram
User β API Gateway β AWS Lambda β Cognito & DynamoDB β Response
βοΈ Step 1: Setting Up the Serverless Project
First, install the Serverless Framework:
npm install -g serverless
Then, create a new project:
serverless create --template aws-nodejs --path serverless-auth
cd serverless-auth
npm init -y
Install dependencies:
npm install express serverless-http @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb @aws-sdk/client-cognito-identity-provider jsonwebtoken dotenv
π Step 2: Define API in serverless.yml
Create serverless.yml
with the following configuration:
service: serverless-auth
plugins:
- serverless-dotenv-plugin
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
environment:
USERS_TABLE: UsersTable
COGNITO_USER_POOL_ID: your-user-pool-id
COGNITO_CLIENT_ID: your-client-id
COGNITO_CLIENT_SECRET: your-client-secret
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
- dynamodb:Scan
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-1:*:table/UsersTable"
functions:
registerUser:
handler: handler.handler
events:
- http:
path: register
method: post
cors: true
- http:
path: users/{userId}
method: get
cors: true
- http:
path: users
method: get
cors: true
- http:
path: users/{userId}
method: put
cors: true
- http:
path: users/{userId}
method: delete
cors: true
loginUser:
handler: handler.handler
events:
- http:
path: login
method: post
cors: true
π Step 3: Implement the Authentication API
Create an app.js
file
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { CognitoIdentityProviderClient, SignUpCommand, InitiateAuthCommand } = require("@aws-sdk/client-cognito-identity-provider");
const { DynamoDBDocumentClient, GetCommand, PutCommand, DeleteCommand, ScanCommand } = require("@aws-sdk/lib-dynamodb");
const express = require("express");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const app = express();
const cognito = new CognitoIdentityProviderClient({ region: "us-east-1" });
const USERS_TABLE = process.env.USERS_TABLE;
const client = new DynamoDBClient({ region: process.env.AWS_REGION });
const docClient = DynamoDBDocumentClient.from(client);
app.use(express.json());
// JWT Authentication Middleware
const authenticate = (req, res, next) => {
const token = req.headers.authorization?.split(" ")[1];
if (!token) return res.status(401).json({ error: "Unauthorized - No token provided" });
try {
const decoded = jwt.verify(token, process.env.COGNITO_PUBLIC_KEY);
req.user = decoded;
next();
} catch (err) {
return res.status(401).json({ error: "Invalid token", details: err.message });
}
};
// Login Route
app.post("/login", async (req, res) => {
const { email, password } = req.body;
const params = {
AuthFlow: "USER_PASSWORD_AUTH",
ClientId: process.env.COGNITO_CLIENT_ID,
AuthParameters: {
USERNAME: email,
PASSWORD: password,
},
};
try {
const response = await cognito.send(new InitiateAuthCommand(params));
res.json({ token: response.AuthenticationResult.IdToken });
} catch (error) {
res.status(400).json({ error: "Could not authenticate user", details: error.message });
}
});
module.exports = app;
π Step 4: Deploy & Test the API
Run the deployment command:
serverless deploy
Use Postman or cURL to test the API:
curl -X POST https://your-api-url/dev/login -H "Content-Type: application/json" -d '{ "email": "test@example.com", "password": "YourPass123" }'
π― Conclusion
In this guide, we built and deployed a serverless authentication system using AWS services. This architecture ensures scalability, cost efficiency, and security. π‘
πΉ Want to enhance this further? Add OAuth2 (Google/Facebook Login) or Multi-Factor Authentication (MFA) for stronger security! π
Let me know if you found this useful! Drop your thoughts in the comments below. π
Top comments (0)