---
# System prepended metadata

title: Bcrypt

---

---
title: "Bcrypt"
disqus: JBeanny
---

By: Yim Sotharoth

Using npm bcrypt package
===

## Table of Contents

[TOC]

## Installation

:::info
_firstly create a node project_
```bash=
$ npm init --y
```

_I named folder as `bcrypt` ( or anything you want ) so I cd in my folder_

> In `bcrypt` folder install a few libraries with the following command

```bash=
$ npm install bcrypt express
```

:::



## Create a simple server with express

> In `index.js` created a simple server like this:

```javascript!
const express = require("express");
const app = express();

app.use(express.json());

app.get("/", (req, res) => {
  res.send("HELLO FROM METAPHORLISM");
});

app.listen(8080, () => {
  console.log(`Server is running on port : 8080`);
});

```

:::success
With this above code we have a GET request on PORT: 8080
:::

___

## Create utility functions

_Created a folder called `utils`_

### Function to encrypt password

> In `utils` I created a file called `PasswordEncoder.js` with the following code:

```javascript!
const bcrypt = require("bcrypt");

const passwordEncoder = async (plainTextPassword) => {
  try {
    return await bcrypt.hash(plainTextPassword, 10);
  } catch (err) {
    throw err;
  }
};

module.exports = passwordEncoder;
```

___

### Function to compare password

> In `utils` I created a file called `PasswordValidator.js` with the following code:

```javascript!
const bcrypt = require("bcrypt");

const comparePassword = async (plainTextPassword, hashedPassword) => {
  return await bcrypt.compare(plainTextPassword, hashedPassword);
};

module.exports = comparePassword;
```

___

### Function to generate random ID

> In `utils` I created a file called `PasswordValidator.js` with the following code:

```javascript!
const generateRandomId = (length) => {
  let result = "";
  const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
};

module.exports = generateRandomId;
```
___

### Function to generate access token

> In `utils` I created a file called `PasswordValidator.js` with the following code:

```javascript!
const generateAccessToken = (length) => {
  let result = "";
  const characters =
    "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
};

module.exports = generateAccessToken;
```

:::warning
Note that this function is only used for this testing purpose only. It is not secure to generate the token for your production this way.

But you can use JWT to generate the secured access token 

Link: https://www.npmjs.com/package/jsonwebtoken
:::
___

## Temporary data store

> Create a folder called `data` and create a file name `users.json` to store the data

_Demo data structure for `users.json` file will be like this_

```javascript!
[
  {
    "username": "Tharoth",
    "email": "metaphorlism@gmail.com",
    "password": "$2b$10$iVHPveTJzd88fr5qm2KKo.PJqQo3OZDinZ1Ztak4eY8v3FuGMIByi",
    "id": "2iry0owncxjb"
  }
]
```
___

## Create model for the register / login

> Create a folder called `models`

_Create a file called `auth.model.js` inside `models` folder with the following code:_

```javascript!
const fs = require("fs");

const filePath = `${__dirname}/../../data/users.json`;

const users = JSON.parse(fs.readFileSync(filePath, "utf-8"));

class Auth {
  register(user) {
    users.push(user);
    fs.writeFileSync(filePath, JSON.stringify(users), "utf-8", (err) => {
      if (err) return err.message;
    });
  }

  findUserByEmail(email) {
    return users.find((usr) => usr.email === email);
  }
}

module.exports = new Auth();
```

:::info
Use node file system (fs) library to read/write data from the `users.json` file
:::

## Create controller for the register / login

> Create a folder called `controllers`

_Create a file called `auth.controllers.js` inside `controllers` folder with the following code:_

```javascript!
const AuthModel = require("../models/auth.model");
const passwordEncoder = require("../utils/PasswordEncoder");
const comparePassword = require("../utils/PasswordValidator");
const generateRandomId = require("../utils/RandomIdGenerator");
const generateAccessToken = require("../utils/TokenGenerator");

class Auth {
  async register(req, res) {
    try {
      //encrypt the user input password before storing to the json file
      req.body.password = await passwordEncoder(req.body.password);
      req.body.id = generateRandomId(12);

      AuthModel.register(req.body);

      res.status(201).json({
        status: "Success",
        message: "User created successfully !",
      });
    } catch (error) {
      res.status(500).json({
        status: "Fail",
        message: error.message,
      });
    }
  }

  async login(req, res) {
    try {
      //find if user exists
      const user = AuthModel.findUserByEmail(req.body.email);

      // if user exists
      if (user) {
        // compare the input password and the stored password
        if (await comparePassword(req.body.password, user.password)) {
          // generate access token with the length of 100
          const token = generateAccessToken(100);
          return res.status(200).json({
            status: "Success",
            message: "Login Successfully !",
            token: token,
          });
        }
        // if compare failed
        return res.status(403).json({
          status: "Fail",
          message: "Incorrect Login Credentials !",
        });
      }

      // if user is not found
      res.status(400).json({
        status: "Fail",
        message: `No user with email: ${req.body.email}`,
      });
    } catch (error) {
      res.status(500).json({
        status: "Fail",
        message: error.message,
      });
    }
  }
}

module.exports = new Auth();
```

## Create routes for the register / login

> Create a folder called `routes`

_Create a file called `auth.routes.js` inside `routes` folder with the following code:_

```javascript!
const express = require("express");
const router = express.Router();

//controller
const Auth = require("../controllers/auth.controller");

router.post("/register", Auth.register);
router.post("/login", Auth.login);

module.exports = router;
```

## Modify the `index.js`

```javascript!
const express = require("express");
const app = express();

app.use(express.json());

app.get("/", (req, res) => {
  res.send("HELLO FROM METAPHORLISM");
});

//routes
const AUTH = require("./src/routes/auth.routes");

app.use("/auth", AUTH);

app.listen(8080, () => {
  console.log(`Server is running on port : 8080`);
});

```

## Demo

> Register

_Postman_

![](https://hackmd.io/_uploads/BkmjyCrHn.png)

_After sending request we can see the data is inserted into `users.json`_

![](https://hackmd.io/_uploads/BkfkgRBrn.png)

> Login

![](https://hackmd.io/_uploads/B17GxRHSn.png)


> Project Repository : https://github.com/metaphorlism/npm-libraries/tree/npm-bcrypt

### Contact Us

- :mailbox: yimsotharoth999@gmail.com
- [GitHub](https://github.com/metaphorlism) 
- [Facebook Page](https://www.facebook.com/Metaphorlism)
- [Instagram: Metaphorlism](https://www.instagram.com/metaphorlism/)
