How to use authentication in full stack web app built with ReactJS and HapiJS using JWT : Part 1

Siddharth Lakhara
5 min readAug 1, 2018

Authentication is an important topic irrespective of the kind of development that you are doing. I, being a web developer was curious to learn authentication in a web app. In this blog, I share my knowledge gained during the journey. I will demonstrate how authentication can be applied in the Javascript environment. This is a two part blog series where we will be building a full stack application on ReactJS and HapiJS. Although, the application is built on a particular stack, you can transfer this knowledge to any stack that you want to work on. We will use JWT for authentication. JWT or JSON Web Token is used for token based session management.

In this part we will discuss the overview of what we are going to implement. And, the implementation of backend. Before beginning development, I would like to talk a bit about authentication, which is our main focus.

Authentication, Session management and JWT

Source: https://cdn.auth0.com/blog/cookies-vs-tokens/cookie-token-auth.png

There are two types of authentications, i.e. cookie based and token based. Token based authentication being the modern approach. In cookie based authentication, a unique identifier, like username is taken as authentication record. This method is stateful. Hence, once the user is successfully logged in, the authentication record is maintained at the server and client. At the client, the record is stored in cookies. For every subsequent requests, user sends the record from cookie, and the server validates the request before serving it. This approach is simple, however not scalable. The reason being record keeping of all logged in users at the server, doesn’t make it ideal for a serving a wider population.

Token based authentication, is stateless. Hence, doesn’t requires the server to store valid auth records. Since, the token is not stored in cookie, we don’t get CORS issues, which is added advantage. The user needs to send the token with every request. The token contains encoded user information. This token is first validated, and then the response is served. The token validation is done by verifying the information contained in it, or verifying the signature of the information. The advantage of this approach is, the server does not have to store any token information. All the relevant information can be derived from the token. Hence, making it ideal to implement for scalability.

JSON web tokens or JWT in short, enables developers to implement token based authentication easily. Once the user is authenticated and token received, all further requests should carry this token. The server should display pages according to the permissions defined by the token. If you would like to learn more about JWT and its structure. You can refer to the following medium article I found interesting:

This article explains about the JWT and its structure in easy to understand manner. Also, if you want an even in depth tutorial, you can head over to the official blog of Auth0, who developed JWT.

So now that we know what is JWT and authentication in general, what are we waiting for? Let’s get started building our application

Tech stack

Database: Postgres (https://www.postgresql.org/)
ORM: Sequelize (http://docs.sequelizejs.com/)
Back end: HapiJS (https://hapijs.com/)
Front end: ReactJS (https://reactjs.org/)
Authentication (token based auth): JWT (https://jwt.io/)

Overview of app

Backend routes:
/login - allows users to login
/register - allows users to register themselves
/info - A protected route for fetching current user details
Front end routes:
/login - opens login user form
/register - opens register user form
/ - Front Page. Displays content according login state of user

See the full code here:
Backend, Frontend

The code uses ES7 async await. If you don’t know how to setup babel transpiler for this, look at my blog describing it

Bootstrapping HapiJS server with JWT auth

To allow our NodeJS server to search for auth header, we need to add
hapi-auth-jwt2 plugin. The code, for your reference is provided follow:

The part of the code relevant to us is init function. It registers required JWT plugin. Then, defines the strategy for authentication we will be using. You can refer to the syntax of server.auth.strategy here. The above written code makes use of validate function imported from utils folder. The use of this function is essentially to validate a JWT auth token. Requirements of such function can be defined as:

  1. Verify the signature of token
  2. For a valid token, verify the user is present and the token has not yet expired

The code is as follows:

Code for validating token

Writing Login API

Our /login route should do the following tasks:

  1. Validate userName and password fields are provided in the request
  2. Verify the existence of user, and send appropriate response
  3. If the user is present, compare the password; and
  4. Generate a JWT token and send it back to user

Notice, since, the user won’t have a token before logging in, auth on this route needs to be set to false. The config, hence need to look similar to this:

config: {  
auth: false
}

The full login route can be viewed here.

To generate a token, the code makes use of createToken function which essentially generates a JWT token. Such function can be defined as follows:

Writing user info API

The aim of /info API is to provide user information on receiving a valid token. Since, our server is configured with JWT strategy. We don’t need to write the validator code again. Our server will handle it. We will be focusing on API functionality, which is as follows:

  1. Get user id from auth token
  2. Fetch the user info from database using the user id obtained in previous step
  3. Send back all this information to the front end

The API is described here.

If you want to use the information inside the auth token, it can be accessed in way describe below:

With this we can conclude the completion of our backend server. We will now focus on the front end, which will be developed on ReactJS. Goto next article

If you like this post, please click 👏 on to show appreciation. Follow me on Github

--

--

Siddharth Lakhara

Full stack developer @Cisco, Ex-@McKinsey | Bibliophile | Coder by heart | Opinions are mine