Forgot Password
In this tutorial, we’ll build a flow allowing an experience user to reset his/her forgotten password. We’ll follow a standard forgot password flow found on the web:
- The user requests to reset their password by providing his/her email address.
- Soon after, the user receives an email with a generated link to reset the password.
- After clicking the provided link, the user supplies his/her email address again along with a new password.
- If the email matches the token in the provided link, the user’s password is changed to the new one he/she provided.
Create the Endpoints
We’ll be adding four endpoints, all of which will be hit by a user going through the password reset flow. In “Edit” in the experience menu, click the “Endpoints” tab, then click the “Add” button at the top right of the list.
GET /forgot-password
This endpoint is responsible for handling requests to view the “Forgot Password” page. Here we will simply render a form for collecting the user’s email address. From the “New Endpoint” page …
- Leave the
Method
set asGET
. - Set the
Route
to/forgot-password
. - Change the
Access Control
toAll public users
.
Save the route, then return to the endpoints list page and click “Add” to add the next route.
POST /forgot-password
This endpoint is responsible for handling submissions of the “Forgot Password” form. From the “New Endpoint” page …
- Set the
Method
toPOST
. - Set the
Route
to/forgot-password
. - Change the
Access Control
toAll public users
.
Remember to save the route, and then create the next endpoint.
GET /reset-password
This endpoint is responsible for handling requests to view the “Reset Password” page, which is where an experience user lands after clicking the reset link in his/her email. From the “New Endpoint” page …
- Leave the
Method
set asGET
. - Set the
Route
to/reset-password
. - Change the
Access Control
toAll public users
.
POST /reset-password
Finally, this endpoint is responsible for handling submissions of the form on the “Reset Password” page, which collects the user’s email address and a new password. This is the last step before the password is actually reset.
- Set the
Method
toPOST
. - Set the
Route
to/reset-password
. - Change the
Access Control
toAll public users
.
Save the route, then return to the endpoints list page and click “Add” to add the next route.
Create the Views
Now that all the endpoints have been created, let’s move on to creating our new views. We’ll be creating two new pages: one for requesting a password reset, and one for fulfilling the password reset request.
Page: Forgot Password
First we’ll create a new page to render when the /forgot-password
endpoint is requested. From here, users can enter their account email address and request a password change. Click “Views” in the left column to return to your Experience Views list, then click the “Add” button in the “Pages” list.
Name
the pageForgot Password
.- Add a description if you would like; the field is optional and does not affect the page as it is presented to your experience users.
- Select your previously created layout for the page’s
Layout
. - Choose
Custom
for thePage Type
. - Copy this snippet and paste it for the page’s
Content
.
Once the page is ready, click “Create Page” to save your work.
Page: Reset Password
Next, we’ll add a page for where the actual password reset takes place. This is the page users will see after clicking the password reset link in their email. In it, we ask them to confirm their email address and enter a new password.
Name
this new pageReset Password
.- Select the same
Layout
as for your other pages. - Choose
Custom
for thePage Type
. - Copy this code to serve as the page’s
Content
.
Set a JWT Secret
The backbone of the password reset flow is a JSON Web Token that we will send to the user via email. To encode this token on creation, and to decode it when we are ensuring the user is who they say they are as they are resetting their password, we will need to sign the token with a secret, which must be shared between our /forgot-password
and /reset-password
endpoints.
We’ll set this secret as an application global so that both of the workflows we create in the next step can access it. To create the global, click “Settings” in your application navigation bar, then click “Globals” in the left column.
- Set the
Key
asjwtSecret
. - Leave the
Type
asString
. -
For the value, enter a random alphanumeric string that is at least 8 characters long. We recommend using this random string generator …
- Change the number of strings to
Generate
to1
. - Change the length to
16
characters long
. - Make sure to check all three character boxes (
Numeric
,Uppercase
andLowercase
). - Click the “Get Strings” button at the bottom of the page, and your random string will be displayed on the next page.
- Copy the string and set it as the value of your new application global.
- Change the number of strings to
Save your new global, and then move on to creating the workflows.
Create the Workflows
Though a user most frequently completes a forgot password flow while logged out (i.e. because they cannot log in to their account), we will still allow signed-in users to complete the flow as part of our walkthrough. This is because we are requiring authenticated users who wish to change their password to enter their current password, and it is certainly possible for a user to have forgotten it while still in an active session.
Let’s continue with the model we’ve followed so far by including the GET and POST methods for each route within the same workflow. Click the “Workflows” menu item, so we can create some new experience workflows.
Forgot Password Workflow
- Download the workflow template, then import the file
endpoint-forgot-password.flow
as a new experience workflow. - Update each of the endpoint triggers to point to the
POST /forgot-password
andGET /forgot-password
endpoints you created above. - Update the endpoint reply nodes to point to your
Forgot Password
page. - Enable the workflow (since imported workflows are by default disabled).
As a general overview, this workflow handles the following:
- If a user visits
/forgot-password
, we respond to the request with our newForgot Password
page. -
When that user submits the
Forgot Password
form, we validate that they have submitted all fields correctly and try to find an experience user matching that email.- If we find a user, we generate a JWT token (using the secret we created earlier) and send it via email to that user. The token expires after 24 hours.
- If we do not find a user, we still send an email to the address that was entered, stating that an attempt was made to reset a password for that user but we do not have the user on file. This is helpful to somebody who has multiple email addresses and cannot remember which they used to sign up for your experience account.
- Whether or not we find a user, we reply to the request with a confirmation message to the form submitter. This is a security feature that prevents people from spamming your experience with loads of email addresses to determine who has an account.
There is a comment on each workflow node describing its function in more detail.
Reset Password Workflow
Now let’s create a workflow allowing users to reset their passwords after clicking the token they were emailed above.
- Download the workflow template, then import the file
endpoint-reset-password.flow
as a new experience workflow. - Update each of the endpoint triggers to point to the
POST /reset-password
andGET /reset-password
endpoints you created above. - Update the endpoint reply nodes to point to your
Reset Password
page. - Enable the workflow (since imported workflows are by default disabled).
As a general overview, this workflow handles the following:
-
First, we make sure ALL of the following are true; if any of these fail, we redirect the user back to
/forgot-password
with an error message …- There is a token on the request as a query parameter, and it is a valid token (e.g. it hasn’t expired).
- The token maps to a valid experience user, and that user’s email address has not changed since the password reset was requested.
- The user’s password has not been reset since the token was issued.
- If this is a GET request (i.e. the user clicked the email link), we render the Reset Password page.
-
If the user is submitting the form, we make sure of the following …
- The user’s new password is a valid password.
- The email address matches the address in the token.
- If the above checks pass, we set the user’s new password, generate a new auth token while logging them out of other sessions, and redirect to the home page.
There is a comment on each workflow node describing its function in more detail.
Link to the Feature
A “Forgot Password” link is typically found on an application’s “Log In” page, directly beneath the password input. We’ll put a link in exactly the same spot, and since we’re also allowing signed-in users to kick off the forgot password flow, we’ll add the same link on the in-session “Change Password” page.
Immediately beneath the user’s current password <input>
tag, add the following line:
<span class="help-block"><a tabindex="-1" href="/forgot-password">Forgot password?</a></span>
Alternatively, you can download the updated Log In page and the updated Change Password page.
Review
Now it is possible for our experience users to reset their forgotten password, which, combined with our user registration and user profile management walkthroughs, completes the self-serve user management experience.
Was this page helpful?
Still looking for help? You can also search the Losant Forums or submit your question there.