Dung (Donny) Nguyen

Senior Software Engineer

Implementing AWS Cognito Authentication in Web Apps

Here’s how to implement AWS Cognito authentication in our web application:

  1. First, set up our Cognito User Pool in AWS Console:
    • Create a User Pool
    • Configure sign-in options (email, username, phone)
    • Set password policies
    • Create an app client
    • Note down the User Pool ID and App Client ID
  2. Install the required dependencies:
    npm install @aws-amplify/auth amazon-cognito-identity-js
    
  3. Implements following features:
    • User registration and confirmation
    • Sign-in and sign-out
    • Password reset flow
    • Session management
    • Protected API requests
// Install required packages:
// npm install @aws-amplify/auth amazon-cognito-identity-js

import { Auth } from '@aws-amplify/auth';

// Configure AWS Amplify
const configureAuth = () => {
  Auth.configure({
    region: 'OUR_REGION',
    userPoolId: 'OUR_USER_POOL_ID',
    userPoolWebClientId: 'OUR_CLIENT_ID',
    oauth: {
      domain: 'our-domain.auth.region.amazoncognito.com',
      scope: ['email', 'profile', 'openid'],
      redirectSignIn: 'http://localhost:3000/',
      redirectSignOut: 'http://localhost:3000/',
      responseType: 'code'
    }
  });
};

// User Registration
const signUp = async (username, email, password) => {
  try {
    const { user } = await Auth.signUp({
      username,
      password,
      attributes: {
        email
      }
    });
    console.log('Sign up successful:', user);
    return user;
  } catch (error) {
    console.error('Error signing up:', error);
    throw error;
  }
};

// Confirm Registration
const confirmSignUp = async (username, code) => {
  try {
    await Auth.confirmSignUp(username, code);
    console.log('Verification successful');
    return true;
  } catch (error) {
    console.error('Error confirming sign up:', error);
    throw error;
  }
};

// Sign In
const signIn = async (username, password) => {
  try {
    const user = await Auth.signIn(username, password);
    console.log('Sign in successful:', user);
    return user;
  } catch (error) {
    console.error('Error signing in:', error);
    throw error;
  }
};

// Sign Out
const signOut = async () => {
  try {
    await Auth.signOut();
    console.log('Sign out successful');
  } catch (error) {
    console.error('Error signing out:', error);
    throw error;
  }
};

// Password Reset Request
const forgotPassword = async (username) => {
  try {
    await Auth.forgotPassword(username);
    console.log('Password reset code sent');
  } catch (error) {
    console.error('Error requesting password reset:', error);
    throw error;
  }
};

// Confirm Password Reset
const confirmForgotPassword = async (username, code, newPassword) => {
  try {
    await Auth.forgotPasswordSubmit(username, code, newPassword);
    console.log('Password reset successful');
  } catch (error) {
    console.error('Error resetting password:', error);
    throw error;
  }
};

// Get Current Authenticated User
const getCurrentUser = async () => {
  try {
    const user = await Auth.currentAuthenticatedUser();
    console.log('Current user:', user);
    return user;
  } catch (error) {
    console.error('Error getting current user:', error);
    return null;
  }
};

// Get JWT Token
const getCurrentSession = async () => {
  try {
    const session = await Auth.currentSession();
    return {
      accessToken: session.getAccessToken().getJwtToken(),
      idToken: session.getIdToken().getJwtToken(),
      refreshToken: session.getRefreshToken().getToken()
    };
  } catch (error) {
    console.error('Error getting current session:', error);
    return null;
  }
};

// Protected API Request Helper
const makeAuthenticatedRequest = async (url, options = {}) => {
  try {
    const session = await getCurrentSession();
    if (!session?.accessToken) {
      throw new Error('No active session');
    }

    const response = await fetch(url, {
      ...options,
      headers: {
        ...options.headers,
        Authorization: `Bearer ${session.accessToken}`
      }
    });
    return response.json();
  } catch (error) {
    console.error('Error making authenticated request:', error);
    throw error;
  }
};

  1. Basic usage examples:
// Initialize the configuration
configureAuth();

// Register a new user
await signUp('username', 'user@example.com', 'password123');

// Confirm registration with code
await confirmSignUp('username', '123456');

// Sign in
await signIn('username', 'password123');

// Make authenticated API request
const data = await makeAuthenticatedRequest('https://api.example.com/protected-route');
  1. Important security considerations:
    • Store User Pool configuration in environment variables
    • Implement proper error handling
    • Use HTTPS for all API endpoints
    • Implement token refresh handling
    • Consider implementing Multi-Factor Authentication (MFA)