Building Secure User Registration and Authentication in Node.js
Tags: node, javascript, beginners, tutorial
Published: 2023-11-11 11:00:00

### Table of Contents
- [Introduction](#intro)
- [Install Dependencies](#install-dep)
- [Generate JWT Token](#jwt-token)
- [Register User](#register-user)
- [Authenticate User](#login-user)

> *For this series, I'm following an excellent video tutorial from [Traversy Media](https://www.youtube.com/playlist?list=PLillGF-RfqbbQeVSccR9PGKHzPJSWqcsm)*


### Introduction <a name="intro"></a>
To get started with user registration and authentication, we'll begin by installing the necessary dependencies. Specifically, we'll use the `bcryptjs` library to securely store user passwords as hashes, and the `jsonwebtoken` library to generate JSON Web Tokens (JWT) for user authentication.
 

### Install Dependencies <a name="install-dep"></a>
Firstly, let's install the required libraries:
```javascript
npm i bcryptjs
npm i jsonwebtoken
```


### Generate JWT Token <a name="jwt-token"></a>
In this step, we are creating a function to generate a JWT token to use later. Write this function in `userController.js` file.
```javascript
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const asyncHandler = require("express-async-handler");
const User = require("../models/userModel");

// Generate JWT
const generateToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, { expiresIn: "30d" });
};
```
Don't forget to initialize the `JWT_SECRET` variable in your `.env` file. You can choose any suitable value for it.


### Register User <a name="register-user"></a>
Now, we'll write down the logic for registering a user in `userController.js` file.
```javascript
const registerUser = asyncHandler(async (req, res) => {
  const { name, email, password } = req.body;

  if (!name || !email || !password) {
    res.status(400);
    throw new Error("Please add all fields");
  }

  // check if user exists
  const userExists = await User.findOne({ email });
  if (userExists) {
    res.status(400);
    throw new Error("User already exists");
  }

  // create hash password
  const salt = await bcrypt.genSalt(10);
  const hashedPassword = await bcrypt.hash(password, salt);

  // create user
  const user = await User.create({
    name,
    email,
    password: hashedPassword,
  });

  if (user) {
    res.status(201).json({
      _id: user.id,
      name: user.name,
      email: user.email,
      token: generateToken(user._id),
    });
  } else {
    res.status(400);
    throw new Error("Invalid user data");
  }
});
```

Let's test the registration process using Postman and ensure everything works as expected. 

![register user postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4slyc3zmugpkyyw7yrp2.png)

And it'll show an error if you try to add the same user again.

![register user error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewaekdjaxzls9x2kcgs6.png)


### Authenticate User <a name="login-user"></a>
To enable authentication for a registered user, we will implement a 'Login User' function within the `userController` file, which will involve verifying the user's identity by comparing their provided email and password.
```javascript
const loginUser = asyncHandler(async (req, res) => {
  const { email, password } = req.body;

  if (!email || !password) {
    res.status(400);
    throw new Error("Please add all fields");
  }

  // Check for user email
  const user = await User.findOne({ email });

  if (user && (await bcrypt.compare(password, user.password))) {
    res.json({
      _id: user.id,
      name: user.name,
      email: user.email,
      token: generateToken(user._id),
    });
  } else {
    res.status(400);
    throw new Error("Invalid credentials");
  }
});
```
Let's test the login process with correct and incorrect credentials.

![login postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0acttgnqjjgcck520nz.png)

![login error postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykz5kuog68ittu4fu4jm.png)

In the next article, we'll work on Authentication Middleware and also create a new API to get logged-in user data.

Connect with me
- [LinkedIn](https://www.linkedin.com/in/aneeqa-khan-990459135/)
- [GitHub](https://github.com/AneeqaKhan)