Skip to main content

Amazon Cognito

Initial Setup

This package provides integration with Amazon Cognito for authentication using FIDO2 standard. It simplifies the process of adding and signing in with a passkey in a Cognito User Pool with custom authentication.

The AWS setup is crucial for this integration to work and can be achieved by following this guide.

Required settings:

  • Cognito User Pool ID
  • Cognito Client ID

Add SDK to Existing Application

npm install --save @loginid/cognito-web-sdk

Create an SDK Instance

NPM
import { LoginIDCognitoWebSDK } from "@/loginid/cognito-web-sdk";

const USER_POOL_ID = process.env.COGNITO_USER_POOL_ID;
const CLIENT_ID = process.env.COGNITO_USER_CLIENT_ID;
const LOGINID_BASE_URL = process.env.LOGINID_BASE_URL;

const config = new LoginIDCognitoWebSDK(
USER_POOL_ID,
CLIENT_ID,
LOGINID_BASE_URL
);

API Reference

LoginIDCognitoWebSDK Class

Constructor

Creates a new instance of the LoginIDCognitoWebSDK class.

createPasskey

Create a passkey for the specified username using FIDO2 create operation.

createPasskey(username: string, authzToken: string, options?: CustomAuthenticationOptions): Promise<AuthResult>

ParameterTypeRequiredDetails
usernamestryesThe username of the Cognito user.
authzTokenstryesThe authorization token can be Cognito ID token or access token associated with the user.
optionsCustomAuthenticationOptionsnoAdditional options for custom authentication.
options.metaDataobjectnoAdditional metadata for the custom authentication process during VerifyAuthChallenge Lambda phase.
options.displayNamestringnoA human-palatable name for the user account, intended only for display on your passkeys and modals.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const handlerSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

try {
// called after successful authenticated session with signup and autoSignIn or signin with password
const token = loginid.getSessionInfo().idToken;
if (token) {
await Loginid.createPasskey(username, token);
}
} catch (e: any) {
setError(e.message);
}
};

authenticateWithPasskey

Signs in with a passkey for the specified username using FIDO2 get operation.

authenticateWithPasskey(username: string, options?: CustomAuthenticationOptions): Promise<AuthResult>

ParameterTypeRequiredDetails
usernamestryesThe username of the Cognito user.
optionsCustomAuthenticationOptionsnoAdditional options for custom authentication.
options.metaDataobjectnoAdditional metadata for the custom authentication process during VerifyAuthChallenge Lambda phase.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const handlerSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

try {
const result = await Loginid.authenticateWithPasskey(username);
if (result.isAuthenticated) {
// handle success
} else {
// handle fallback options
}
} catch (e: any) {
setError(e.message);
}
};

authenticateWithPasskeyAutofill

Signs in with passkey autofill or conditional UI using LoginID SDK.

This method initiates a sign-in process with passkey autofill or conditional UI elements. It leverages WebAuthn to provide a secure, usernameless authentication.

authenticateWithPasskeyAutofill(options?: CustomAuthenticationOptions): Promise<AuthResult>

ParameterTypeRequiredDetails
optionsCustomAuthenticationOptionsnoAdditional options for custom authentication.
options.metaDataobjectnoAdditional metadata for the custom authentication process during VerifyAuthChallenge Lambda phase.
options.abortControllerAbortControllernoAn AbortController to optionally abort the conditional UI authentication.

For this to work, make sure you have an input field within a form element that has the webauthn value added to autocomplete.

<form>
<input
id="email"
name="email"
type="email"
autocomplete="username webauthn"
/>
</form>
import { useEffect, useState } from "react";

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const passwordLessLogin = function () {
const [abortController] = useState(new AbortController());

// On page load or component load
useEffect(() => {
const conditionalUI = async () => {
try {
const options = { abortController: abortController };
await Loginid.authenticateithPasskeyAutofill(options);
} catch (e) {
setError(e.message);
}
};

conditionalUI();

return () => {
abortController.abort();
};
});
};

signUpWithPassword

Signs up a user and password using a cognito sdk signup method.

This method creates a new Cognito user with a password and email as username. LoginID provides this wrapper signup function on top of Cognito signup SDK to simplify the integration process.

signUpWithPassword(email: string, password: string, confirmPassword: string, autoSignIn: boolean): Promise<AuthResult>

ParameterTypeRequiredDetails
emailstryesThe email address of the user.
passwordstryesThe password of the user.
confimPasswordstryesThe confirm password of the user must match password field.
autoSignInbooleanyesSet whether auto sign-in after successful sign-up

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const registerUser = async (
email: string,
password: string,
confirmPassword: string
) => {
try {
const autoSignIn = true;
const result = await Loginid.signUpWithPassword(
email,
password,
confirmPassword,
autoSignIn
);
// will need to confirm user after signup if auto confirmation and autoSignIn is false
} catch (e: any) {
console.error("Error during sign up:", e.message);
}
};

signUpPasswordless

Signs up a user using a passwordless method.

This method creates a new Cognito user with a generated password and email as username. It simplifies the user registration process by eliminating the need for a password. This emulates a passwordless sign up experience. LoginID provides this wrapper signup function on top of Cognito signup SDK to simplify the integration process.

note

Cognito requires users to sign up with a password. The password is randomly generated and discarded, only to be used for signup.

signUpPasswordless(email: string, autoSignIn: boolean): Promise<AuthResult>

ParameterTypeRequiredDetails
emailstryesThe email address of the user.
autoSignInbooleanyesSet whether auto sign-in after successful sign-up

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const registerUser = async (email: string) => {
try {
const result = await Loginid.signUpPasswordless(email);
// will need to confirm user after signup if auto confirmation and autoSignIn is false
} catch (e: any) {
console.error("Error during sign up:", e.message);
}
};

requestAndSendOtp

Request and Send the email OTP authentication process for a user.

This method initiates the email OTP authentication process for a given email address. It sets the current Cognito user and prepares them for completing the OTP verification. This method requires custom auth lambdas setup included in passkey and email otp example flow.

Requires:

  • Verified email or domain with SES

requestAndSendOtp(email: string, method: string, options?: CustomAuthenticationOptions): Promise<null>

ParameterTypeRequiredDetails
emailstryesThe email address of the user.
methodstryesThe delivery method default = "email" user.
optionsCustomAuthenticationOptionsnoAdditional options for custom authentication.
options.metaDataobjectnoAdditional metadata for the custom authentication process during VerifyAuthChallenge Lambda phase.

validateOtp

Completes validate the email OTP authentication process for a user.

This method completes the email OTP authentication process by verifying the OTP provided by the user. It finalizes the custom authentication and returns the user session.

Requires:

  • Verified email or domain with SES

validateOtp(otp: string, options?: CustomAuthenticationOptions): Promise<AuthResult>

ParameterTypeRequiredDetails
otpstryesThe one-time password (OTP) received by the user via email.
optionsCustomAuthenticationOptionsnoAdditional options for custom authentication.
options.metaDataobjectnoAdditional metadata for the custom authentication process during VerifyAuthChallenge Lambda phase.

import { useState, useEffect } from "react";

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const EmailOTPLogin = function ({ username }) {
const [otp, setOtp] = useState("");

// On page load or component load
useEffect(() => {
const initalizeOTP = async () => {
try {
// Or invoke this on a click handler
await Loginid.requestAndSendOtp(username);
} catch (e) {
setError(e.message);
}
};

initializeOTP();
}, []);

const handlerSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

try {
const result = await Loginid.validateOtp(otp);
if (result.isAuthenticated) {
// success login
}
} catch (e: any) {
setError(e.message);
}
};
};

listPasskeys

Lists all passkeys for a given user.

Requires one of the following:

  • User must be signed in.
  • Cognito ID token.

listPasskeys(idToken?: string): Promise<PasskeyCollection>

ParameterTypeRequiredDetails
idTokenstrNoThe Cognito ID token of the user.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const listUserPasskeys = async () => {
try {
const passkeys = await Loginid.listPasskeys();
console.log(passkeys);
} catch (e: any) {
console.error(e.message);
}
};

renamePasskey

Renames a specified passkey.

This method updates the name of a passkey identified by the passkeyId. It requires the new name for the passkey.

Requires one of the following:

  • User must be signed in.
  • Cognito ID token.

renamePasskey(passkeyId: string, name: string, idToken?: string): Promise<null>

ParameterTypeRequiredDetails
passkeyIdstryesThe unique identifier of the passkey.
namestryesThe new name for the passkey.
idTokenstrnoThe Cognito ID token of the user.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const renameUserPasskey = async () => {
const passkeyID = "34f4aa64-74e1-4f19-8ee0-939c4d32fe01";

try {
const token = await getCognitoIdToken(user);
await Loginid.renamePasskey(passkeyId, "My Passkey");
console.log("Passkey renamed successfully");
} catch (e: any) {
console.error(e.message);
}
};

deletePasskey

Deletes a specified passkey.

This method removes a passkey identified by the passkeyId from the user's account. It requires the unique identifier of the passkey.

Requires one of the following:

  • User must be signed in.
  • Cognito ID token.

deletePasskey(passkeyId: string, idToken?: string): Promise<null>

ParameterTypeRequiredDetails
passkeyIdstryesThe unique identifier of the passkey.
idTokenstrnoThe Cognito ID token of the user.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const deleteUserPasskey = async () => {
const passkeyId = "34f4aa64-74e1-4f19-8ee0-939c4d32fe01";

try {
const token = await getCognitoIdToken(user);
await Loginid.deletePasskey(token, passkeyId);
console.log("Passkey deleted successfully");
} catch (e: any) {
console.error(e.message);
}
};

logout

Log out the current user.

This method logs out the currently authenticated user from the Cognito user pool.

logout(): void

This method does not take any arguments.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const logoutUser = () => {
Loginid.logout();
console.log("User signed out successfully");
};

getSessionInfo

Gets the current user authetnicated session info.

This method retrieves the SessionInfo of the currently authenticated user from the Cognito user pool.

getSessionInfo(): SessionInfo

This method does not take any arguments.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const getCurrentUser = () => {
const info = Loginid.getSessionInfo();
if (info.username && info.accessToken) {
console.log("Current user:", info.username);
} else {
console.log("No user is currently authenticated");
}
};

getCurrentUsername

Gets the current username.

This method retrieves the username of the currently authenticated user from the Cognito user pool.

getCurrentUsername(): string | null

This method does not take any arguments.

const { COGNITO_CLIENT_ID, COGNITO_USER_POOL_ID, LOGINID_BASE_URL } = config;
const Loginid = new LoginIDCognitoWebSDK(
COGNITO_USER_POOL_ID,
COGNITO_CLIENT_ID,
LOGINID_BASE_URL
);

const getCurrentUser = () => {
const username = Loginid.getCurrentUsername();
if (username) {
console.log("Current user:", username);
} else {
console.log("No user is currently authenticated");
}
};