Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Cognito Authentication

Cameron Wardzala edited this page Apr 10, 2020 · 8 revisions

Many applications require authentication, for future projects we have chosen AWS Cognito to provide this ability. Gateway has a branch to provide scaffolding to implement Cognito authentication.

Setup

This project uses the Authentication API from the AWS amplify-js library.

You do not need to setup or use the Amplify CLI toolchain. We only use the JS API.

src/index.js

Before you can start doing any interactions with Cognito you need to configure Amplify.

Gateway sets up Amplify using two environment variables. These should be set appropriatly for each environment (development, stage, or production) in a .env.{environment} file. You can override locally if necessary in a .env.local file.

  • REACT_APP_USER_POOL_ID - this is the User Pool ID from Cognito
  • REACT_APP_USER_POOL_WEB_CLIENT_ID - the User Pool web client ID
  • REACT_APP_AWS_REGION - the AWS region to use
Amplify.configure({
    Auth: {
        userPoolId: process.env.REACT_APP_USER_POOL_ID,
        userPoolWebClientId: process.env.REACT_APP_USER_POOL_WEB_CLIENT_ID,
        region: process.env.REACT_APP_AWS_REGION
    }
});

Auth Context

Gateway utilizes a React Context Provider to store and manage session data. The core of this functionallity is found in src/context/AuthContext.jsx.

context/AuthContext.jsx

AuthContext.jsx provides multiple exported modules.

Any of these can be imported using the ES6 module import pattern

import { appActions, AuthContext, passwordSchema } from 'path/to/context/AuthContext.jsx';

passwordSchema

This is a password-validator schema to handle validating passwords against defined password requirements.

import { passwordShema } from 'path/to/context/AuthContext.jsx';

passwordSchema.validate('my password');
// true or false

// Return a list of failed validations
// this can be useful when wanting to display
// individual validation errors
let valid = passwordSchema.validate('password', { list: true });
// ['min', 'digits', 'symbols', 'uppercase']

appActions

This is an object of "app action" names, to be used when using dispatch to trigger updates to the AuthContext.

import { AuthContext, appActions } from 'path/to/context/AuthContext.jsx';

const MyComponent = () => {
    const { state, dispatch } = useContext(AuthContext);

    // Do Something
    dispatch({
        type: appActions.PERSIST_LOGIN_START
        //... additional event data
    });
};

AuthContext

This is the "auth" React Context instance. This can be used with useContext to gain access to the context state and dispatch function in a component.

import { AuthContext } from 'path/to/context/AuthContext.jsx';

const MyComponent = () => {
    const { state, dispatch } = useContext(AuthContext);
};

AuthProvider

This is a functional component that is used to provide context to the entire application.

const AppWrapper = () => (
    <Router>
        <AuthProvider>
            <App />
        </AuthProvider>
    </Router>
);

ReactDOM.render(<AppWrapper />, document.getElementById('root'));

Pages

There are a number of pages in src/pages/auth/ that help support and provide interfaces for the Cognito authentication flow.

SignIn.jsx

This page provides email and password inputs, for authenticating against Cognito. After authentication there are multiple possible next-steps taken.

  • Authentication was successful, take action based on the value of user.challengeName.
    • SMS_MFA or SOFTWARE_TOKEN_MFA - This can be used to trigger the flow for collecting a MFA token from the user.
    • NEW_PASSWORD_REQUIRED - Add the user info to the AuthContext and redirect to /new-password-required, so the user can setup a new password.
    • MFA_SETUP - This can be used to trigger the flow for setting up MFA.
    • default - The user info is added to the AuthContext and redirect to /.
  • Authentication was unsuccessful, take action based on error.code.
    • UserNotConfirmedException - The user did not confirm their account when signing up. Use this exception to send a new code and display the confirmation code entry experience.
    • PasswordResetRequiredException - The password was reset by an admin in Cognito. Display a message to the user, "Your password has been reset by an administrator. You should have received an email with a password reset code.".
    • NotAuthorizedException - The password provided was incorrect, highlight the "password" input and display the message from error.message.
    • UserNotFoundException - The username/email provided does not exist in the Cognito user pool. Highlight the "email" field and display the message from error.message.
    • default - Display error.message.

Register.jsx

This page provides fields to register a user base on the user pool attributes required to sign-up. After registration there are multiple possible next-steps taken.

  • Registration was successful
    • User will be redirected to the login screen.
  • Registration was unsuccessful
    • Display message from error.message.

NewPasswordRequired.jsx

This page allows the user to setup a new password after authentication.

  • Set password was successful
    • Display <ChangePasswordConfirm> with link to sign-in page.
  • Set password was unsuccessful
    • Display message from error.message

ForgotPasswordVerification.jsx

This page allows the user to setup a new password after requesting a "Forgot Password" code. The user will be required to enter their "code", email address, and new password.

  • Set password was successful
    • Display <ChangePasswordConfirm> with link to sign-in page.
  • Set password was unsuccessful, take action based on error.code
    • CodeMismatchException or ExpiredCodeException - Highlight the "code" input and display the message from error.message.
    • InvalidPasswordException - Highlight the "password" input and display the message from error.message.
    • default - Display the message from error.message.

ForgotPassword.jsx

This page allows the user to request a "forgot password" code.

  • Request successful
    • Display a message that the email was sent, and provide a link to /forgot-password-verification.
  • Request unsuccessful
    • Display message from error.message.