Implement Dynamic Login: Using Regex in MongoDB Queries
Tags: webdev, programming, beginners, tutorial
Published: 2024-03-03 17:38:40

## Introduction

The conventional login pattern, where an active user in the application is required to provide email and password, or just username and password fields to login, will be considered in this article, with the goal of making the login process a bit more flexible.

We could consider a scenario where we want the active user to be able to supply either their **email** or **userName** or even **firstName** and **password** to login successfully on the application, making the entire login process less subjective.

To achieve this flexibility in login, we’ll be using **Regular Expressions (Regex)** in MongoDB to achieve this purpose. Regex will help us perform a case-insensitive search for any item provided by the user.

_By case-insensitivity, we want the user to be at liberty to type in records in uppercase, lowercase or a combination of both_.

## Using $regex in MongoDB Query

According to the MongoDB atlas documentation [read here](https://www.mongodb.com/docs/manual/reference/operator/query/regex/#-regex), **$regex**
Provides regular expression capabilities for pattern matching strings in queries.

$rejex can be used following this syntax pattern:

```javascript
{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ "<field>": { "$regex": "pattern", "$options": "<options>" } }
{ <field>: { $regex: /pattern/<options> } }
```

From the above illustration on how the $regex syntax pattern can be used, we'll create a simple router and put this $regex syntax patter to use. 

First, we install bycrpt library to help us compare user inputted password with the stored password on the database. We can then achieve our dynamic login query by using this line of code:

```javascript
import User from "/models/userModel";
import bcrypt from "bcryptjs";

UserAuthRouter.post("/login", async (req, res) => {
const {userId, password} = req.body;

const user = await User.findOne({ $and: [{isActive: true},

{$or: [{email:{$regex: new RegExp('\\b'+ userId +'\\b','i')}},

{userName:{$regex: new RegExp('\\b'+ userId +'\\b', 'i')}}]} 

]});

if(user){
    if (bcrypt.compareSync(password, user.password)) {
        return res.status(200).send({
          _id, userId,
          message: "successfully loggedin",
          success: true
        })
      }
    res.status(401).send({ message: "Invalid userId or 
    password" })
}
res.status(401).json({ message: "Invalid userId or password"});
});
```

## The Key Takeaway

From the foregoing, we have combined two comparison operators (**$and** & **$or**) in MongoDB to help ensure that only an active user (isActive) whose userId matches either the **email** or **userName** field in the user collection, will be granted access to login.

We also used $regex to do a full text case-insensitive search, and below is a brief breakdown of the regex pattern used.

1. **Flexibile Matching:** The regex pattern '\\b' + userId + '\\b' is used to match   The '\\b' denotes word boundaries, ensuring that the email address or userName is matched as a complete word and not as part of a larger string.

2. **Case-insensitivity Matching:** The 'i' flag in the regex constructor ('i') ensures search case-insensitive. This means that the regex will match email addresses or userNames regardless of whether they are written in uppercase, lowercase, or a combination of both. This ensures that the search is inclusive and captures all possible variations of the email address or userNames.


## Conclusion

By using regex, we can efficiently retrieve documents from the database that meet specific criteria. This flexibility enables robust search functionality and enhances the overall user experience.

Feel free to add more search conditions that aligns with your requirements and also remember that the goal is to make user experience a lot more stress free. 👍  

I would love to know how you handle user login in your applications and also don't forget to like, comment and share this article with others. Until next time, remain inspired. 😊