Using the AWS SDK's admin commands with Authsignal's pre-built UI
Learn how to integrate Authsignal when using AWS Cognito and admin commands from the AWS SDK.
This guide will demonstrate how to use the pre-built UI in redirect mode to present a passwordless challenge to the user on login.
It shows how to use the Authsignal Node SDK in your Cognito lambdas as well as the Authsignal Web SDK in your web app.
The web app is a SPA which makes requests to a Node/Express backend.
The backend uses the following commands from the @aws-sdk/client-cognito-identity-provider
package to talk to Cognito:
- AdminInitiateAuth
- AdminRespondToAuthChallenge
- AdminCreateUser
- AdminSetUserPassword
Example code
You can find the full example code on Github.
User flow
The user enters their email to sign in.
The user is redirected to Authsignal to complete a challenge.
The user is redirected back to the client which then fetches an access token from Cognito.
Sequence diagram
Installation
Install the required npm modules with yarn (or npm) in both the SPA and backend folders:
yarn install
Running the SPA
yarn run dev
Running the backend
COGNITO_CLIENT_ID=<ID_HERE> COGNITO_CLIENT_SECRET=<SECRET_HERE> COGNITO_USER_POOL_ID=<USER_POOL_ID_HERE> node app.js
User pool settings
For this example there are several important settings to configure when creating a Cognito User Pool:
Step 1
Choose Email
as the sign-in option.
Step 2
Choose No MFA
as the MFA option.
This can be implemented with Authsignal instead.
Step 3
Disable self-registration
because we are creating users from our backend.
Step 4
Disable the Cognito Hosted UI
.
The SPA replaces this.
Step 5
Select Confidential client
for the app type. Also select Generate a client secret
.
The lambdas
The example repo contains four lambdas which can be deployed to your AWS environment.
Once deployed, these lambdas can be connected to your Cognito user pool:
Create Auth Challenge lambda
This lambda uses the Authsignal Node.js SDK to return a short-lived token back to the app which can be passed to the Authsignal Web SDK to launch the Authsignal pre-built UI in a popup:
export const handler: CreateAuthChallengeTriggerHandler = async (event) => {
const userId = event.request.userAttributes.sub;
const email = event.request.userAttributes.email;
// This can be any value which defines your login action
const action = "cognitoAuth";
const { url } = await authsignal.track({
action,
userId,
email,
});
event.response.publicChallengeParameters = { url };
return event;
};
Verify Auth Challenge Response lambda
This lambda takes the result token returned by the Authsignal Web SDK and passes it to the Authsignal Node.js SDK to validate the result of the challenge:
export const handler: VerifyAuthChallengeResponseTriggerHandler = async (
event
) => {
const token = event.request.challengeAnswer;
const userId = event.request.userAttributes.sub;
// This must be the same value used in the previous step
const action = "cognitoAuth";
const { state } = await authsignal.validateChallenge({
action,
userId,
token,
});
event.response.answerCorrect = state === "CHALLENGE_SUCCEEDED";
return event;
};
Important API calls
The SPA makes use of 4 Cognito API calls via the AWS SDK:
AdminInitiateAuth
This API call is responsible for starting the authentication process.
This API is passed the username and CUSTOM_AUTH
as the authentication flow and returns a URL to Authsignal’s pre-built UI as well as a Cognito session token.
The SPA then redirects to the Authsignal URL which will allow the user to complete a passwordless authentication challenge.
After the challenge is completed the pre-built UI will redirect back to the SPA’s /callback
endpoint with a token in the query string.
AdminRespondToAuthChallenge
This API call is responsible for completing the authentication flow. This API is passed multiple parameters, most importantly the session string, and the Authsignal token as the ANSWER parameter. The return values include both a cognito access and refresh token.
AdminCreateUser
This API call is responsible for adding a user to the user pool.
In this example we first check if a user exists and if they don’t we call this API.
This API is passed a variety of parameters including the email address, which is passed as both the username
and email
.
AdminSetUserPassword
This API call is responsible for setting the user’s password. This API is passed a username and password. We also pass a parameter to make the password permanent rather than temporary. Because the user does not need to be aware of their password, we randomly generate a secure password and use that instead of getting one from the user.
Next steps
Was this page helpful?