NodeJs Authentication With JWT. This is for people who are new to… | by Shelcia David | The Startup | Medium

Photo by Sigmund on Unsplash

NodeJs Authentication With JWT

Shelcia David

The Startup

Shelcia David

·

Follow

Published in

The Startup

·

·

Jan 5, 2021

9 min read

This is for people who are new to NodeJs and trying to figure out how to build basic authentication with JSON web tokens and integrate it with their frontend.

You will either need postman installed on your PC or you can use Postman web with CORS extension enabled for chrome.

In the end of this article you can write routes or services which can be authorised if user is authenticated using JWT tokens.

Pre-requisites :

  • Some knowledge of Javascript
  • Node installed on your PC or laptop
  • VS Code or your favourite code Editor
  • MongoDB account
  • Idea of REST API

Step 1: Introduction

This part consist of basic theory related to NodeJs , JWT and libraries used. You can skip if you are just here for code part.

What is NodeJs?

Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser.

Node.js runs single-threaded, non-blocking, asynchronously programming, which is very memory efficient.

What can it do:

  • Node.js can generate dynamic page content
  • Node.js can create, open, read, write, delete, and close files on the server
  • Node.js can collect form data
  • Node.js can add, delete, modify data in your database

Source and Reference:

Let’s See if you have Node.Js

For that open your terminal and run this

node -v

This is to check if you got NodeJs installed already and its version.

shelciaabi@Shelcias-Air authtentication backend % node -v
v14.15.0

So I have NodeJs version 14.15.0

If you don’t have Node.js download it here ,

What is JWT ?

JSON Web Token is a standard used to create access tokens for an application. It works this way: the server generates a token that certifies the user identity and sends it to the client.

In simpler words JWT Tokens is more like a key. If user is authenticated, the server will give a key(the token) using which the client can now(access) open/use routes or services.

Reference and source:

Dependencies and Libraries Used

  • express

We will be using Express as it provides a robust set of features for our application.

  • mongoose

Mongoose as it provides an extra level of abstraction when it comes to handling database queries and also handles most of the underline logic.

  • bcryptjs

We have used bcryptjs which help us with hashing passwords.

  • dotenv

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

For example if we have SECRET variable stored in our environment file(.env).

We can use it in our node file as process.env.SECRET

  • cors

CORS is a middleware that can be used to enable CORS with various options.

  • jsonwebtoken

JSON web token to generate tokens for client-side authorisation.

  • @hapi/joi

We have installed “@hapi/joi” for input verification.

  • nodemon

nodemon is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.

Step 2: Setting Up

You can skip this section too if you have MongoDB atlas set up and knows how to initialise a node app.

1. Installation

  • open vscode
  • create folder
  • create index.js within your folder
  • then run these commands

npm init

Now press enter till the end(license part) and type “yes” when you prompted with the message IS THIS OK? and..

npm i express mongoose bcryptjs dotenv cors jsonwebtoken @hapi/joi --save

2. Set up MongoDb Atlas

  • create a account
  • log in to account
  • Now Click CREATE CLUSTER

In cloud provider choose a region which is near to your location which has a free tier available. You can any cloud provider(AWS or Google cloud or Azure)

Within Cluster tier -> choose M0 Sandbox (which is free)

Whatever you do make sure in the bottom you are not billed for the usage xD.

I have chosen AWS for cloud provider and Mumbai for locationM0 Sandbox is free forever under certain limits as mentioned.

Creation of cluster can take up around 2- 5 minutes.

Creating the cluster

After the creation of cluster click CONNECT.

If you are a new user then you will be prompted to add IP address and DB username and password.

In the first step -> Add a connection to IP address chose all access from anywhere.

In the next step -> add username and password.

Make sure you remember them as we will need them to connect to the database.

Connection method

And navigate to choose a connection method under which Choose the option 2(Connect your application) to connect to your application.

Choose Node.js from Driver dropdown and version 3.6 or later.

replace dbname and password

You have to copy that link paste it in your .env file

Make sure you replace the dbname with whatever you want your database to have name and password with MongoDB password.

.env file

Now back at the terminal we need one more dependency.

Nodemon is a utility that will monitor for any changes in your source and automatically restart your server.

Let’s install it globally.

npm install -g nodemon

Step 3: Coding

Get the code directly here if you want.

1.Creation of Server

Now let’s create our server.

With the help of express, we can create robust web apps. We import the express module and create instance. With that we will use its functionalities.

On GET request (‘/’) the server will render the message ‘Hey it’s working !!’.

index.js

Now back on your terminal run the command below.

nodemon index.js

Open http://localhost:4050/ in your browser, you will see ‘Hey it’s working !!’.

Are we good till now ?

2. Creating User Schema

It’s good to keep different groups of routes and models in separate folder.

Just like this.

Folder structure

Within models, we are going to create User.js file which will have the user schema.

Here we will have the structure of User. Just like this.

User.js

The entities of User collection will have a first name (fname), last name (lname), email, password and date which will be set to Date.now() as default.

“min” and “max” corresponds to the minimum and a maximum length of the string. “required” is set to true if the field is mandatory.

3. Creating Signup

Now within the routes -> auth.

Create auth.js. Import all modules required.

auth.js

We will have to verify the inputs (like the data type , length of the string., etc)

For that, we will use @hapi/joi which does the job for us. Just like this.

This doesn’t verify the inputs yet.

auth.js

Things we need to keep on our mind before creating user is

  1. Check if email already exists
  2. Check if got the right inputs (jsonwebtoken)
  3. Hash the password (bcryptjs)

We will create an asynchronous function for the same.

We will use the POST method to create a user.

Now back at index.js.

We have to connect to Database and import this route. After which we need to create a route link.

index.js

We don’t have to restart our server as every time we save our file the server is restarted.

Now either open postman web or postman application downloaded on PC.

Postman Web : https://web.postman.co/build#

Use this along CORS extension enabled.

https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en

With this route we should be able to add users

http://localhost:4050/api/users/register

Make sure for response you selected Body -> raw -> JSON

postman

Now try sending same response again. You should get bad request error with the message “Email already exists”.

You can also try removing the fname or have length of the string lesser than 2. We will get the corresponding error.

Awesome !!!.

4. Creating Login

It is similar to signup.

Things to be noted

  1. Check if email exists in database
  2. After getting the user details corresponding to email verify the password with password stored in database after decryption.
  3. Check if we got valid inputs

Now we will use JSON web tokens. Instead of the message “success”, we should send the JWT token.

5. JWT TOKENS

Back at your .env file add TOKEN_SECRET variable.

Add some random string.

.env with TOKEN_SECRET

Now instead of sending success we will sign the user._id(the unique field -> users id) with the TOKEN_SECRET.

complete auth.js

6. Using JWT Token

There should be some routes which should be validated with tokens. For example if we have admin dashboard then the client should have the respective token to access it. JWT Tokens is pretty useful here.

For the sake of creating another route we will create GET api endpoint where in I can fetch all user details only if the client has the token.

For that create authVerify.js and authDashboard.js within our routes -> auth.

If the API request from the client is without the token we will send back “Access Denied”.

After which we need to make sure the token has right to authenticate. We will verify the token and approve if verified.

authVerify.js

To add authentication all we need to do is add import authVerify and add it to the function just like this.

authDashboard.jsfolder structure

Now that we have dashboard route we will have to import it in our index.js and add its route link.

index.js

We can save and check the verification part without the token you will end up with unauthorised error(401). With the right token you get after successful login you can use it to fetch user details.

Without tokenwith token

7. Sending request from frontend with token

Once user login is successful we will get token from backend which can be stored in localStorage.

With “axios” you can do something like this.

import axios from "axios";

const token = localStorage.getItem("token");

const url = `http://localhost:4050/api/dashboard/allusers;
const headers =
{
"auth-token": token,
"Content-Type": "application/json",
Accept: "application/json",
};
const getUsers = () => {
axios.get(url, { headers: headers })
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
};

Conclusion

Bye !