Crafting a Secure Authentication System with JWT and middleware
Tags: node, tutorial, beginners, javascript
Published: 2023-11-18 11:00:00

### Table of Contents
- [Introduction](#intro)
- [Create protect middleware](#protect-middleware)
- [Get current user data](#current-user)
- [Protect the user data route](#protect-routes)

> *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>
In this blog, we'll dive into the development of a robust authentication system for your application. We'll start by creating a `protect` middleware that ensures the safety of our users' data.

### Create protect middleware <a name="protect-middleware"></a>
Firstly, we'll start with creating an `authMiddleware.js` file in the `middleware` folder. 
```javascript
const jwt = require("jsonwebtoken");
const asyncHandler = require("express-async-handler");
const User = require("../models/userModel");

const protect = asyncHandler(async (req, res, next) => {
  let token;
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith("Bearer")
  ) {
    try {
      // get token from header
      token = req.headers.authorization.split(" ")[1];

      // verify token
      const decoded = jwt.verify(token, process.env.JWT_SECRET);

      // get user from the token
      req.user = await User.findById(decoded.id).select("-password");

      next();
    } catch (error) {
      console.log(error);
      res.status(401);
      throw new Error("Not Authorized");
    }
  }
  if (!token) {
    res.status(401);
    throw new Error("Not Authorized, no token");
  }
});

module.exports = { protect };
```
In this function, we retrieve the token from the request headers and verify it to determine if the decoded token's `id` matches any user in the database. If it doesn't find a user or if the token is missing, in such cases, we throw an error.

### Get current user data <a name="current-user"></a>
Next, we'll create a function to get the currently logged-in user data in `userController.js`.
```javascript
const getLoggedInUser = asyncHandler(async (req, res) => {
  const { _id, name, email } = await User.findById(req.user.id);
  res.status(200).json({
    id: _id,
    name,
    email,
  });
});
```

### Protect the user data route <a name="protect-routes"></a>
In the last, We'll use `protect` middleware to secure the user data route. Add these lines to the `userRoutes.js` file.
```javascript
// import middleware
const { protect } = require("../middleware/authMiddleware");

...
// Add a protect as a second param
router.get("/me", protect, getLoggedInUser); 
...
```

Now, let's check this functionality with no token

![no jwt token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui52unmnlkk5bkikx5xm.png)

Now add the correct token

![secure user data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7td7af70bt2madcg4qj1.png) 

And now test it with an invalid token

![invalid token](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6r3wckp32tjoqsodgr0.png)

That's it for today. In the next article, we'll work on protecting the todos routes.

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