Forgot Password

In this tutorial, you’ll build a flow that allows an experience user to reset his/her password. You’ll follow a standard reset password flow from on the web:

  1. The user requests to reset their password by providing his/her email address.
  2. Soon after, the user receives an email with a generated link to reset the password.
  3. After clicking the provided link, the user supplies his/her email address again along with a new password.
  4. If the email matches the token in the provided link, the user’s password is changed to the new one he/she provided.

Forgot Password Overview

Step One: Create the Endpoints

You’ll add four endpoints, all of which will be encountered by a user going through the password reset flow:

GET /forgot-password

This endpoint is responsible for handling requests to view the “Forgot Password” page. Here you will render a form for collecting the user’s email address. From the “New Endpoint” page:

  1. Leave the Method set as GET.
  2. Set the Route to /forgot-password.
  3. Change the Access Control to All public users.
  4. Save the route.
  5. Return to the “Endpoints” list.
  6. Click “Add” to add the next route.

POST /forgot-password

This endpoint is responsible for handling the “Forgot Password” form submissions. From the “New Endpoint” page:

  1. Set the Method to POST.
  2. Set the Route to /forgot-password.
  3. Change the Access Control to All public users.
  4. Save the route.

Once complete, 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:

  1. Leave the Method set as GET.
  2. Set the Route to /reset-password.
  3. Change the Access Control to All public users.

POST /reset-password

The final 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 reset:

  1. Set the Method to POST.
  2. Set the Route to /reset-password.
  3. Change the Access Control to All public users.
  4. Save the route.
  5. Return to the endpoints list page and click “Add” to add the next route.

Step Two: Create the Views

Now that all the endpoints have been created, it is time to create your new views. You’ll create two new pages: one for requesting a password reset, and one for fulfilling the password reset request.

Add Page

Page: Forgot Password

First you’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:

  1. Click “Views” in the left column to return to your Experience Views list.
  2. Click the “Add” button in the “Pages” list.
  3. Name the page Forgot Password.
  4. Add a description. This field is optional and does not affect the page as it is presented to your experience users.
  5. Select your previously created layout for the page’s Layout.
  6. Choose Custom for the Page Type.
  7. Copy this snippet and paste it for the page’s Content.
  8. Once the page is ready, click “Create Page” to save your work.

Page: Reset Password

Next, 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, you ask them to confirm their email address and enter a new password.

  1. Name this new page Reset Password.
  2. Select the same Layout as for your other pages.
  3. Choose Custom for the Page Type.
  4. Copy this code to serve as the page’s Content.

Step Three: Set a JWT Secret

The backbone of the password reset flow is a JSON Web Token that you send to the user via email. To encode this token on creation, and to decode it when you ensure the user is who they say they are as they are resetting their password, you need to sign the token with a secret, which must be shared between your /forgot-password and /reset-password endpoints.

JWT Secret

You’ll set this secret as an application global so that both of the workflows you create in the next step can access it. To create the global:

  1. Click “Settings” in your application navigation bar.
  2. Click “Globals” in the left column.
  3. Set the Key as jwtSecret.
  4. Leave the Type as String.
  5. For the value, enter a random alphanumeric string that is at least 8 characters long. This random string generator is recommended:
    • Change the number of strings to Generate to 1.
    • Change the length to 16 characters long.
    • Make sure to check all three character boxes (Numeric, Uppercase and Lowercase).
    • 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.

Random.org Generator

  1. Save your new global, and then move on to creating the workflows.

Step Four: Create the Workflows

Because you are requiring authenticated users who wish to change their password to enter their current password, it is possible for a user to have forgotten it while still in an active session.

Continue with the model you’ve followed so far by including the GET and POST methods for each route within the same workflow. Click the “Workflows” menu item, so you can create new experience workflows.

Forgot Password Workflow

Forgot Password Workflow

  1. Download the workflow template, then import the file endpoint-forgot-password.flow as a new experience workflow.
  2. Update each of the endpoint triggers to point to the POST /forgot-password and GET /forgot-password endpoints you created above.
  3. Update the endpoint reply nodes to point to your Forgot Password page.
  4. 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, you respond to the request with your new Forgot Password page.
  • When that user submits the Forgot Password form, you validate that they have submitted all fields correctly and try to find an experience user matching that email.
    • If you find a user, you generate a JWT token (using the secret you created earlier) and send it via email to that user. The token expires after 24 hours.
    • If you do not find a user, you still send an email to the address that was entered, stating that an attempt was made to reset a password for that user but you do not have the user on file. This is helpful to someonw who has multiple email addresses and cannot remember which they used to sign up for your experience account.
  • Whether or not you find a user, you 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.

Reset Password Workflow

  1. Download the workflow template, then import the file endpoint-reset-password.flow as a new experience workflow.
  2. Update each of the endpoint triggers to point to the POST /reset-password and GET /reset-password endpoints you created above.
  3. Update the endpoint reply nodes to point to your Reset Password page.
  4. Enable the workflow (since imported workflows are by default disabled).

As a general overview, this workflow handles the following:

  1. You make sure ALL of the following are true; if any of these fail, you 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.
  2. If this is a GET request (i.e. the user clicked the email link), you render the Reset Password page.
  3. If the user is submitting the form, ensure the following:
    • The user’s new password is a valid password.
    • The email address matches the address in the token.

There is a comment on each workflow node describing its function in more detail.

A “Forgot Password” link is typically found on an application’s “Log In” page, directly beneath the password input. You’ll put a link in the same spot, and since you’re also allowing signed-in users to kick off the forgot password flow, you’ll add the same link on the in-session “Change Password” page.

Forgot Password Link

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>

Review

Now it is possible for your experience users to reset their forgotten password, which, combined with your user registration and user profile management walkthroughs, completes the self-serve user management experience.