- React Authentication App with Amazon Cognito and API Integration
This project is a React-based web application that demonstrates user authentication using Amazon Cognito. It includes features such as user registration, login, profile management, and access to protected routes. The application also integrates with a custom API built with AWS Lambda and API Gateway to fetch and display user analytics data.
The main purposes of this application are:
- To showcase a robust authentication system using Amazon Cognito in a React application.
- To demonstrate the integration of a React frontend with AWS services (Cognito, Lambda, API Gateway).
- To provide a template for developers looking to implement similar authentication flows in their projects.
- To display how to create and consume protected API endpoints.
-
Frontend:
- React.js
- React Router for navigation
- AWS Amplify for AWS service integration
- Recharts for data visualization
- Tailwind CSS for styling
-
Backend:
- Amazon Cognito for user authentication
- AWS Lambda for serverless backend logic
- AWS API Gateway for API management
- Python for Lambda function
- User signs up with email, username, and password
- User confirms signup with a verification code sent to their email
- User logs in with username and password
- Upon successful authentication, user is granted access to protected routes
- User can view their profile, access analytics, and log out
Before you begin, ensure you have the following installed:
- Node.js (v14 or later)
- npm (v6 or later)
- AWS CLI
- An AWS account with appropriate permissions
-
Clone the repository:
git clone https://github.com/labeveryday-cloud-projects/react-cognito-analytics-dashboard.git cd react-cognito-analytics-dashboard
-
Install dependencies:
npm install
Before you can login to the application you will need to setup a Cognito User Pool and App Client. To send request to the backend you will need to create a lambda function and deploy an API gateway that contains a Cognito authorizer. I have provided all of the needed instructions below:
- Go to the Amazon Cognito Console
- Create a new User Pool
- Configure sign-in options (email, username)
- Set password strength requirements
- Configure MFA settings (optional)
- Add an app client (with no secret)
- Note down the User Pool ID and App Client ID
-
Go to the AWS Lambda Console
-
Create a new function
-
Choose Python 3.x as the runtime
-
Use the following code for your Lambda function:
import json
import random from datetime import datetime, timedelta
def lambda_handler(event, context): print(event) try: origin = event['headers'].get('origin', '')
# CORS headers
cors_headers = {
'Access-Control-Allow-Origin': 'http://localhost:3000',
'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
}
if origin == "http://localhost:3000":
print(f"Authorized origin: {origin}")
# Simulate fetching user analytics data
user_data = generate_user_analytics()
print(user_data)
return {
'statusCode': 200,
'body': json.dumps(user_data),
'headers': cors_headers
}
else:
print(f"NOT Authorized! origin: {origin}")
return {
'statusCode': 403,
'body': json.dumps('Forbidden: Unauthorized origin'),
'headers': cors_headers
}
except Exception as e:
print(f"Error: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps('Internal Server Error'),
'headers': cors_headers
}
def generate_user_analytics(): # Generate mock data for the last 7 days end_date = datetime.now() start_date = end_date - timedelta(days=7)
data = []
current_date = start_date
while current_date <= end_date:
data.append({
'date': current_date.strftime('%Y-%m-%d'),
'activeUsers': random.randint(1000, 5000),
'newSignups': random.randint(50, 300),
'pageViews': random.randint(10000, 50000),
'avgSessionDuration': round(random.uniform(120, 600), 2) # in seconds
})
current_date += timedelta(days=1)
return {
'userAnalytics': data,
'totalActiveUsers': sum(day['activeUsers'] for day in data),
'totalNewSignups': sum(day['newSignups'] for day in data),
'totalPageViews': sum(day['pageViews'] for day in data),
'avgSessionDuration': round(sum(day['avgSessionDuration'] for day in data) / len(data), 2)
}
5. Deploy the Lambda function
### Step-3: API Gateway Setup
1. Go to the API Gateway Console
2. Create a new REST API
3. Create a new resource (e.g., /data)
4. Create a `GET` method for this resource
5. Integrate the GET method with your Lambda function (select lambda proxy)
6. Enable CORS for the resource:
- Access-Control-Allow-Origin: '*'
- Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
- Access-Control-Allow-Methods: 'GET,OPTIONS'
7. Create a Cognito User Pool Authorizer
8. Apply the authorizer to your GET method
9. Deploy the API and note down the invoke URL
## Step-4: Configuration
1. Rename the file named `_aws-exports_update_me.js` in the `src` directory to `aws-exports.js` then modify the following content with your own account info:
```javascript
const awsmobile = {
"aws_project_region": "YOUR_REGION",
"aws_cognito_region": "YOUR_REGION",
"aws_user_pools_id": "YOUR_USER_POOL_ID",
"aws_user_pools_web_client_id": "YOUR_APP_CLIENT_ID",
"aws_cloud_logic_custom": [
{
"name": "MY-API-GATEWAY-NAME",
"endpoint": "YOUR_API_GATEWAY_ENDPOINT",
"region": "YOUR_REGION"
}
]
};
export default awsmobile;
- Open the
src/components/UserAnalytics.js
file and replace the placeholder information with your own api gateway name and resource name.
const restOperation = get({ apiName: 'UPDATE-ME-my-api', path: 'UPDATE-ME-my-api-resource' });
To start the development server:
npm start
The app will be available at http://localhost:3000
.
src/
├── components/
│ ├── Home.js
│ ├── LandingPage.js
│ ├── Login.js
│ ├── Profile.js
│ ├── SignUp.js
│ └── UserAnalytics.js
├── App.js
├── index.js
├── aws-exports.js
└── index.css
NOTE: Don't forget to rename
_aws-exports_update_me.js
toaws-exports.js
and update with your cognito and API gateway info.
App.js
: Main component handling routing and protected routesLandingPage.js
: Initial page users see, with options to sign in or sign upSignUp.js
: Handles user registration and confirmationLogin.js
: Manages user authenticationHome.js
: Protected route showing user dashboardProfile.js
: Displays and manages user profile informationUserAnalytics.js
: Fetches and displays user analytics data
The App.js
file sets up the main structure of the application, including:
- Routing using React Router
- Protected routes using a custom
ProtectedRoute
component - Amplify configuration for API calls
- Implements a two-step registration process: initial sign-up and confirmation
- Uses Amplify's
signUp
andconfirmSignUp
functions
- Handles user authentication using Amplify's
signIn
function - Manages form state and error handling
- Display user-specific information
- Include sign-out functionality
- Use the
user
prop passed from theProtectedRoute
component
- Fetches data from the custom API using Amplify's API module
- Displays data using Recharts for visualization and a detailed table
The application uses AWS Amplify for:
- User authentication (Cognito)
- API calls (API Gateway)
- Managing AWS resource configuration
The application integrates with a custom API built with AWS Lambda and API Gateway:
- The API endpoint is defined in
aws-exports.js
- API calls are made using Amplify's API module in the
UserAnalytics
component - The Lambda function generates mock user analytics data
- API Gateway manages the API, including Cognito-based authorization
The application uses Tailwind CSS for styling, providing:
- Consistent design across components
- Responsive layout
- Easy customization
When deploying this application:
- Ensure all AWS resources (Cognito, Lambda, API Gateway) are properly configured for production use
- Update CORS settings in API Gateway to allow requests from your production domain
- Configure environment variables for sensitive information
- Consider using AWS Amplify for easy deployment and continuous integration
- This application is for demonstration purposes and may need additional security measures for production use
- Regularly update dependencies to ensure security and compatibility
- Consider implementing refresh token handling for extended user sessions
Common issues and solutions:
- CORS errors: Ensure API Gateway CORS settings are correct
- Authentication failures: Verify Cognito setup and
aws-exports.js
configuration - API call failures: Check Lambda function logs and API Gateway settings
For any other issues, please check the AWS documentation or open an issue in the project repository.
My passions lie in building cool stuff and impacting people's lives. I'm fortunate to weave all these elements together in my role as a Developer Advocate. On GitHub, I share my ongoing learning journey and the projects I'm building. Don't hesitate to reach out for a friendly hello or to ask any questions!
My hangouts: