How to Verify Users in Express.js

Kelvin
Kelvin
Dec 30, 2020 · 6 min read
Image for post
Image for post

If you’re building an application, you likely want a lot of users on your platform. However, you don’t just want a large number of users, you want real and high-quality users who will interact with your app. You want to verify those users.

It’s common for bots or users with fake email addresses and no intention of seriously using your application to register. One way to deal with this at the start is by making sure to verify users.

This article is a tutorial on user verification in ExpressJS and a continuation of my Express web development series. I will be building on top of the concepts discussed in my previous article on handling password resets.

The setup and required packages are specified in that article but you will be able to see what packages are used in the code examples.

I’d suggest taking a look at the other articles in the series first, although you should be able to follow along with this one regardless. Check out the project on GitHub if you’d like to track it as the series progresses.

Models

Let’s first create the model that holds the verification tokens. Navigate to the models folder and create a file called ‘UserVerification.js’. The file should have the following content:

const { Schema, model } = require('mongoose')

The model schema contains a token that will be included in the verification link, and the user it’s associated with.

Create an index on the ‘updatedAt’ field that instructs MongoDB to delete the record after 5 minutes from the time the record is updated. 5 minutes is reasonable for testing but you’ll want to increase this to something more reasonable in production.

In the user model, add a boolean ‘verified’ property to the schema. Set the default to false as the user would not be verified upon registration.

const { Schema, model } = require('mongoose')

Routes

Profile routes

The first route we have to create is the profile route. This route will simply render a template with the user’s profile details. Create a file in the routes folder named ‘profile.js’ and add a route that renders the ‘profile.html’ template.

const router = require('express').Router()

User verification routes

Now let’s create the routes that will handle user verification. In the routes folder, create a file named ‘user-verification.js’. To start with, the file will have the following contents:

const router = require('express').Router()
const { v4 } = require('uuid')
const { User, UserVerification } = require('../models')
const { sendEmail } = require('../helpers')

Import the User and UserVerification models. Import the ‘sendMail’ helper function that we created in the previous article. This is simply a function that uses NodeMailer to send an email using the arguments passed to it.

Now let’s create the routes.

Create verification url

The first route is a get route ‘/verify’. This route is responsible for creating the verification URL and has the following contents:

router.get('/verify', async (req, res) => {
if (!req.isAuthenticated()) return res.redirect('/login')
if (req.user.verified) return res.redirect('back')

First, check if the user is authenticated. The user should only be able to request a verification link when they are logged in. If they aren’t, redirect them to the login page.

Check if the user is already verified. We don’t want to send a verification link if the user is already verified. If they are, redirect to the previous page.

Create the token and then the verification URL that contains the token.

Update the UserVerification record associated with the current user. Make sure to set the upsert option to ‘true’. We want to replace the current verification link so that only one can be active at a time, but we also want to create a new one if there isn’t one in the collection.

Send the email containing the user verification link, flash a success message urging the user to check their email address and then redirect to the user’s profile.

Verify user

The second route handles the link sent to the user:

router.get('/verify-confirm/:token', async (req, res) => {
if (!req.isAuthenticated()) return res.redirect('/login')

const token = req.params.token

This route expects a token which we will validate later. First check whether the user is logged in, if not, redirect to the login page.

Extract the token from the url and query the UserVerification collection for a document with the current token and the current user.

If the document doesn’t exist, flash an error message stating that the link is invalid or expired.

If the document exists, update the user’s verified status to ‘true’ and delete the current UserVerification document in order to prevent the link from being clicked again (this would be pointless anyway but it’s good practice).

Send the user an email confirming their verification status and then flash a success message stating that the user has now been verified. Redirect to the user’s profile page afterwards.

Import routes

Go into the app’s entry folder and include the profile and user-verification routes with the following code:

app.use('/', require('./routes/profile')) 
app.use('/', require('./routes/user-verification'))

Templates

There’s one new template that we need to create for this feature: the profile template.

{% extends 'base.html' %}

This template renders the error or success message flashed in the previous request. We have a div that displays the user’s name and a button to generate the verification URL conditionally based on the user’s verified status.

Conclusion

In this article, I demonstrated how to verify users in your Express application. There are many reasons you may want to verify users: You may want to make sure you have active, human users on your app or maybe you want to restrict features that require users to be verified.

Whatever the reason, I hope that this article has provided sufficient guidance on the flow and execution of the verification process.

The next article will be about creating user following and follower relationships using many-to-many relationships in MongoDB.

If you enjoyed this article, consider following my personal website for early access to my content before it gets published on Medium. Also, feel free to comment on this post. I’d love to hear your thoughts!

Originally published at https://kelvinmwinuka.com on December 30, 2020.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store