Responsive web design | Bootstrap | Node.js | Auth0
By: Souvik Paul
Tags: Auth0, Nodejs, Bootstrap, Web Development, Expressjs

The objective of this article is to develop an application for a hypothetical organization that will authenticate users and then it will allow them to perform CRUD operations on an employee database of the organization.

Photo by UX Store on Unsplash

Project Outline

Our project is basically based on federated identity flow, which is described below.

The user tries to access the resource handled my resource server. The server redirects the user to the authorization server as he is not having proper credentials to access the resource. The authorization server is configured to let users login using the credentials managed by an identity provider. Authorization server redirects the user to the login page of the identity provider. After logging-in successfully, the user is redirected to the authorization server along with the credentials provided by the identity provider. These credentials are used by the authorization server to access the credentials required by the resource server. The authorization server redirects the user to the resource server along with the credentials required to access the resource. The user successfully accesses the resource.

In our project, identity provider will be Google, Authorization server will Auth0, Resource server will be programmed by us in Node.js and the resource will be the SQLite3 database.

The following video is the final look of our project.

This project is the extension of another project that I have done and its link is mentioned below. The new features that we’ve added in this one are authentication and authorization using Auth0 and few other modifications on the routes.

For more information, please visit the following blogs.

Tools used

Node.js

Auth0

HTML, CSS, Bootstrap

JQuery

SQLite3

Before beginning the coding part, let me inform you that all the codes that we are going to write are also available in my GitHub repository.

Now, it’s time to start the coding part.

Initial setup

First of all, we’ll create a project directory in our system whose name will be myproject and this directory will have the following files and folders.

We’ll create the database directory and the file inside it, i.e. employees.db will be automatically created by our server application (app.js).

Then, we’ll open the terminal and navigate into this directory and run the command npm init and enter all the default option.

After that, we’ll run the following command to install dotenv, body-parser, express, express-openid-connect, socket.io, and sqlite3.

npm install dotenv body-parser express express-openid-connect socket.io sqlite3 --save

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. With the help of express, APIs can be build very easily and quickly.

Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env . Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology.

Socket.IO — It enables real-time bidirectional event-based communication.

Sqlite3 — Its an asynchronous, non-blocking SQLite3 bindings for Node.js.

express-openid-connect — Express JS middleware implementing sign on for Express web apps using OpenID Connect.

Body-parser is required to handle HTTP POST request in Express.js. It extracts the entire body portion of an incoming request stream and exposes it on req.body .

Now, we’ll go to Auth0 quickstart and select regular web app and follow the instructions there to register our application with Auth0.

It is important to note that, in the callback URL field, we have to enter http://localhost:3000/callback and in the logout URL field, we have to enter http://localhost:3000.

After that, we’ll create a .env file in the root of our myproject directory where we’ll enter the following information.

ISSUER_BASE_URL=https://example.us.auth0.com

CLIENT_ID=mYexampleC1i3ntId

BASE_URL=http://localhost:3000

SECRET=aNyRanDomStuFftHatYoUwaNtT0MenTiOn

Note- Issuer base URL and client ID will be given by Auth0.

Front-end development

Now, we’ll develop the front-end of our application that is present in public directory.

First of all, we’ll create the file login.html, which will be the first page that will be displayed when the user will types http://localhost:3000 and this page will ask the user to login.

After successful login, the user will be landed into index.html page which has the following codes.

The codes for other html files are available in my GitHub repo.

Backend development

Now we’ll write the code for our resource server.

To understand socket.IO, please visit this link —

Testing the Application

Finally, our application is ready. We can start the server using node app command and in browser type http://localhost:3000.

Role of Auth0

Now, it is the good time to understand how Auth0 is managing things. Given below is the description of the entire process.

The browser reaches out to the resource server (app.js in our case) and attempts to access a resource in /protected route with the following request.

2. The OIDC middleware that we have installed (express-openid-connect in our case) intercepts this call and emits an authorization request to the authorization server in response (which is given below) to the above GET request. This is done by redirecting the browser.

In the above response, the meaning of all the parameters are described as follows.

Location: It is the authorization endpoint in the authorization server.

client_id: It is the identifier of our resource server at the authorization server.

response_type: It is the artifact that the browser and middleware wants. In this case, the user wants to sign-in. So, he needs an ID token.

response_mode: It is the way in which the browser and middleware wants the artifacts to be returned. Here, we have all the methods that HTTP allows. We can get the artifacts in the query string but its a bad idea as this will be logged into the browser’s history. So, we’ll use ‘form_post’, which will send the token to the resource server as POST request.

redirect_uri: It represents the address in our resource server where we want the tokens and artifacts to be returned. Tokens we use in this context are bearer tokens.

scope: It represents the artifacts that is being asked from the authorization server.

nonce: The nonce parameter is used for preventing token injection. At request time, a unique identifier is generated and saved in the browser. this identifier is sent to the authorization server and eventually the ID token received back have a claim containing the same identifier. At that point, this can be compared with the saved identifier and we’ll be assured that we got back the token that we requested.

OAuth and OIDC defines the response_type and their default response_mode as follows -

In our case, in the response of the middleware, it has response_type=id_token and instead of using the default response_mode , the middleware has overridden that and used response_mode=form_post .

3. As the browser got 302 status from the middleware in our resource server, it will send a GET request (which is given below) to the authorization endpoint ( /authorize ) in the authorization server with all the parameters supplied by the middleware.

Now, authorization server will do whatever it deems necessary to authenticate the user. The procedure for this is not specified by OAuth or OIDC. Many types of authentication can be used like single-factor, multi-factor etc.

4. When the user is successfully authenticated with the authorization endpoint, typically the authorization server will set a cookie, which represents the session of the user with authorization server. So that if later on, the user again hits the authorization endpoint, he’ll not have to sign-in again.

In response to previous GET request, authorization server will send the following.

In this response, the ID token (JWT format) that was requested has been returned as a parameter in the form. And on the <body> tag of the HTML, an onload event is wired up to submit the form automatically as soon as this page gets rendered, it’s going to POST this token to the resource server.

5. As the browser receives the previous response from the authorization server, the form with token ID is immediately sent to the resource server as a POST request, which is given below.

6. The middleware will intercept the id_token and compares it to check whether that id_token is intended for it or not. If validation is successful, id_token will be accepted and the OIDC middleware on behalf of the resource server will give a 302 response (redirect).

With this response, OIDC middleware will set its own cookie between the browser and the resource server. So that resource server will not need to get the ID token again. At the same time, this response will redirect the user to the original route that he was trying to access along with a cookie.

7. In the redirect process, the browser will send a GET request which is similar to the very first request. Only difference here is that a cookie will be included in every request.

8. Finally, the user will get access to the resource that he was trying to access.

References

Bootstrap 4: https://getbootstrap.com/

Express module: https://www.npmjs.com/package/express

sqlite3 module: https://www.npmjs.com/package/sqlite3

body-parser module: https://www.npmjs.com/package/body-parser

Socket.io: https://socket.io/

Dotenv: https://www.npmjs.com/package/dotenv

express-openid-connect: https://www.npmjs.com/package/express-openid-connect

Auth0 Docs: https://auth0.com/docs/quickstarts/

Video on Authentication for web applications using OpenID Connect: https://auth0.com/docs/videos/learn-identity-series/web-sign-in