Create a secure password reset function
Learn how to make a secure password reset function using a token
Creating the Token model
The first thing we have to do is create the Token model (preferably with an expiration date for extra security) and give the Token model a relation to the web user. The relation should be a Many to one relation (many Tokens to one Webuser). The Token model will end up looking like this:
Go to Roles and permissions and set read to filtered and apply the following filter so that the user can see their own tokens. If you don’t want this, you can set read to ‘not allowed’.
Password reset request action
This action is the first one of two. This one creates a token and sends an email to the user after requesting a new password.
In the action start, add an input variable called email_address:

And make an action variable called ‘existing_webuser’, using the webUser model and set the filter to ‘Email address’ from the webUser table = email_address (the input variable):
The first step in this action is a conditional to if the user exists. You can throw an error when the user does not exist.
Caution: Showing the user an error message like “User does not exist” allows potential attackers to guess email addresses until there is no error message. A better message would be “An email with a recovery link will be sent if we locate the account” or “An email with a recovery link will be sent”
If the user does exist we can do the following steps:
1. Generate a token by using the custom generate token function and name the result random_hex (you can put in any number for the size, we chose 16 for the example).
2. Use another custom function called a Date/time offset, which will be used to create our token expiration date. In the block's options, you should enable the “Use the current date/time” option and set the offset to your desired time.
3. To avoid the user using the same token multiple times, we should add a Delete Many Records step right before creating a new token.
4. Add a Create Record step with the following configuration:
5. The last thing to do in this action is send the reset password link to the web user. We can do this using the Send Email step. In the content of the email, add the link to your reset password page, with the generated token behind it. Example of a password reset email:
After adding the last step, your action should look like this:
Reset password action
The second action is the action connected to the reset password form.
1. At the action start, make 3 input variables: confirm_password, new_password and inputToken, these are the variables that get sent to the action from within the form.
2. Make an action variable, use an Object and then use the WebUser model.
3. Set up the following filter for the action variable: tokens.token equals inputToken
4. Make another Date/time offset, of which the offset will be one second into the future and set the result to ‘now’
5. Drag in a Condition step and give it the following variable. Use the Token model and call it conditionToken and set up the following filter(s).
- token equals inputToken
- (optional, only if you're using tokens for multiple use cases) token_type equals password reset
6. After setting up the variable, we’ll make the actual condition, the action can go through if:
- conditionToken exists
- (optional, only if you're using tokens for multiple use cases) conditionToken.token_type equals PasswordReset
- conditionToken.token_expiration is after or at now
7. Make another condition that checks if the new_password and the confirm_password are the same. To do this you can set up the following rule:
- New_password equals confirm_password
If this condition is true the action can go on, else throw an error which tells the user the passwords do not match.
8. Drag in an Update Record step and use the webuser model for the record. At the value mapping, set the Password property to new_password
If you’ve followed along, your action should look something like this.
If you've followed all the steps correctly, your new secure password reset function should work. Try it out yourself by resetting your password.