How to use authentication in full stack web app built with ReactJS and HapiJS using JWT : Part 1
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
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.
JSON Web Tokens (JWT) in Auth0
JSON Web Token (JWT) is an open standard ( RFC 7519) that defines a compact and self-contained way for securely…
So now that we know what is JWT and authentication in general, what are we waiting for? Let’s get started building our application
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
/login - allows users to login
/register - allows users to register themselves
/info - A protected route for fetching current user detailsFront end routes:
/login - opens login user form
/register - opens register user form
/ - Front Page. Displays content according login state of user
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:
- Verify the signature of token
- For a valid token, verify the user is present and the token has not yet expired
The code is as follows:
Writing Login API
/login route should do the following tasks:
- Validate userName and password fields are provided in the request
- Verify the existence of user, and send appropriate response
- If the user is present, compare the password; and
- 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:
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:
- Get user id from auth token
- Fetch the user info from database using the user id obtained in previous step
- 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: