In this guide, you'll learn how to implement your own custom account recovery page that is powered by the Authentication Flow API.
Before we continue, here's an overview of our objectives for this post:
What we will build
At the end of this guide we'll build a custom account recovery UI using Express.js that will do the following:
Allow users to enter the phone number associated with their account as login ID.
Send an account recovery code to the phone number.
Provide a UI for the user to enter and verify the recovery code.
Finally, a UI for the user to set a new password for their account.
Pre-requisites
To follow this guide, you should have the following:
installed on your local machine.
A code editor like VS Code, Sublime, Atom, or any editor you already use for JavaScript development.
Be comfortable working with CLI tools like NPM.
Last but not least, an Authgear account. Sign up for free .
Step 1: Set up your Authgear Project to use Custom UI
Using custom UI in your Authgear application requires setting the value for Custom UI URI to where your custom UI is hosted.
To set this value, log in to the Authgear Portal and navigate to Applications then select your application. Next, in your application's configuration page, scroll down to the Custom UI section and enter the URL for your custom UI.
For the example in this post, we'll be using CloudFlare Tunnel to expose the custom UI we'll be building so that we can have a public URL to enter in the Custom UI URI field in our Authgear application configuration.
If you're new to the Authentication Flow API, check this getting started post [HERE(LINK)] to learn more about configuring your project for the API.
Step 2: Create Express project
Now let's create the Express project that we'll be using to implement the account recovery Custom UI.
To create a new Express project create a new folder with the name "custom-recovery" on your computer using a file explorer or using the following command in PowerShell or Terminal:
mkdir custom-recovery
This folder will serve as your Express project folder.
Next, install the Express package by running the following command:
npm i express
Finally, create a new JavaScript file with the name "app.js" in the new folder you created earlier. This is the file where we'll implement our application logic.
Add the following code to the new app.js file:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send(`
<p>A demo for account recovery using authflow API. Click on the following link to try it</p>
<a href="/recovery">Forgot password</a>
`)
});
app.get('/recovery', async (req, res)=> {
res.send("Test recovery");
});
app.listen(port, () => {
console.log(`server started on port ${port}!`);
});
At this point, test your work so far by running the following command from the root of your Express project folder:
node app.js
Step 3: Create account recovery page
Here we'll create the UI for the first page of the recovery flow. This will be a basic webpage with an input field for the user to enter their phone (login id) and a submit button.
Open app.js in your code editor and update the content of the app.get('/recovery') route to the following:
The above code refers to a rawURLQuery() and initRecovery() functions that we've not implemented yet. We'll implement the first function in this step and the second in the next step.
The form we created using the above code looks like this:
Look for the following line of code in your app.js file:
const port = process.env.PORT || 3000;
Then add the following code on a new line just below it:
function rawURLQuery(url) {
const index = url.indexOf('?');
return (index === 0) ? url.substr(index + 1) : "";
}
The above code implements the rawURLQuery() function we mentioned earlier. This function is a helper that helps us extract URL Query from the current request. We need a special URL Query from Authgear in order to get the finish redirect URI at the end of our recovery flow. You can learn more about the URL Query [HERE(LINK)].
Step 3: Initialize the recovery flow
In this step, we'll initialize a new authentication flow of type account_recovery.
For this step and other steps that follow, we'll be making HTTP request to the Authentication Flow API using the Axios node package. Install Axios by running the following command:
npm i axios
Import Axios to your project by adding the following code to the top of app,js:
const axios = require('axios');
Next, again, look for the following line in your app.js file:
const port = process.env.PORT || 3000;
Add the following code on a new line just below it:
The above code implements the initRecovery() function. The function sends the HTTP request that initializes a new account recovery flow and returns a state_token. We'll use this state_token to continue to the next step of the flow. Hence we are passing the value for state_token to the next step using <input type="hidden">.
In this step, we'll implement the code that will send the recovery code to the user's phone after they enter their phone number on the form and click submit.
Add a new beginRecovery() function to app.js (just below the initRecovery() function) using the following code:
async function beginRecovery(login_id, state_token) {
const url = `${endpoint}/api/v1/authentication_flows/states/input`;
const input = {
"state_token": state_token,
"batch_input": [
{
"identification": "phone",
"login_id": login_id
},
{
"index": 0 //option of the channel the recovery code will be sent to
}
]
};
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
try {
const recoveryIdentityStep = await axios.post(url, input, {
headers: headers
});
return recoveryIdentityStep;
}
catch (error) {
console.log(error.response.data.error);
return error.response;
}
}
The above code sends a request with the user's phone number (login_id) and the position of the channel (index) to which the code should be sent.
To enable Express to process form data correctly, add the following code on a new line to the top of app.js (just below const app = express();):
app.use(express.urlencoded({ extended: true }));
Now create a POST route that will call the beginRecovery() function by adding the following code just below the app.get('/recovery') route:
The code sample above will redirect the user to a setPassword page after successful verification of the recovery code they entered. In the next step, we'll implement the page where the user can set a new password.
Step 6: Implement set new password page
The final step of the account recovery process is for the user to set a new password for their account. In this step, we'll implement the UI for that.
First, add a new route to your app.js to create the UI using the following code:
If the new password is set successfully, the above code will return control to Authgear to complete the rest of the authentication flow and return to your application. This is done by redirecting the client to the finish_redirect_uri.
Conclusion
And there you have it, you've successfully implemented your own custom password recovery UI powered by the Authentication Flow API.
For our example application, we used the phone number as login_id and the channel for receiving the recovery code. In a real app, you may use another channel such as email instead or even support both depending on what is available for the user.