Creating a full-stack MERN app using JWT authentication: Part 1
Tags: node, react, javascript, fullstack
Published: 2019-07-30 13:47:35

---
title: Creating a full-stack MERN app using JWT authentication: Part 1
published: true
tags: node,react,javascript,fullstack
canonical_url: https://blog.logrocket.com/mern-app-jwt-authentication-part-1/
---

![](https://thepracticaldev.s3.amazonaws.com/i/i3jeauevetn20wmylcp3.jpeg)

My greenfield project requires the usual song and dance: authentication. Our client wants to be sassy and found out that the trending tech in authentication is [JWT (JSON Web Token)](https://tools.ietf.org/html/rfc7519), and the pressure soon built up in using it for all authentication purposes.

Being a React person, I don’t mind working on it and learning a new tech, but yeah — that’s why I am here writing my experience on this.

We are building a React frontend that talks to a [.NET Core API Server](https://dotnet.microsoft.com/). The authentication mechanism has been built on JWT on the .NET side of the project. I am implementing the JWT authentication on the frontend using React, and here it goes.

Also, please note that I haven’t added any MongoDB part, yet I referred to it as a MERN stack application — sorry. It just wasn’t in the scope of this article.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## What is JWT?

JSON Web Tokens are an open, industry-standard RFC 7519 method for representing claims securely between two parties. A JWT is a [JSON](https://www.json.org/) response that is defined in RFC 7519 as a safe way to represent a set of information between two parties. The token is composed of a header, a payload, and a signature.

In simple words, a JWT is just a string in the following format:

![JWT String Format](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/jwt-string-format.jpg?ssl=1)<figcaption>JWT string format.</figcaption>

It should be noted that a double **–** quoted string is actually considered a valid JSON response:

```jsx
"header.payload.signature"
```

### JWT flow

Since we are working in a microservice-based architecture, we have got different microservices, one being the Authentication Service. This is one of the backend services that’s written in .NET Core API, which retrieves a user claim based on a reference token in a domain cookie and generates a JWT for this claim.

If a valid JWT is returned, the call is forwarded to the corresponding service, and the JWT is passed in the request header as an OAuth bearer token for further authorization by the backing service.

![JWT Auth Sequence](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/jwt-auth-sequence.jpg?ssl=1)<figcaption>JWT auth sequence represented in a flowchart.</figcaption>

The above sequence can be simplified using the following diagram:

![Simplified JWT Auth Sequence](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/simplified-jwt-auth-sequence.jpg?ssl=1)<figcaption>Simplified representation of JWT auth sequence, courtesy of <a href="https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java%23jwt-authentication">TopTal</a>.</figcaption>

Let’s start building something similar now.

## Prerequisites

As I said, this is a MERN stack application that we are going to build. The obvious requirements are:

- [Node.js](https://nodejs.org/en/) (latest LTS version, please)
- [Visual Studio Code](https://code.visualstudio.com/) (works well with React, as explained by [Wes Bos](https://wesbos.com/uses/) — it’s good, trust me)
- [Google Chrome](https://www.google.com/chrome/) with React DevTools extension (part of my [preferred environment](https://blog.praveen.science/my-personal-development-environment/))
- A good terminal, like [iTerm2](https://www.iterm2.com/) (macOS)

I guess that’s enough for now.

## Creating an Express.js server

Here’s the simplest form of code: `index.js` that says `Hello World!` on the browser when you open the [localhost on port 3000](http://localhost:3000/) after running `node index`:

```jsx
const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => res.send("Hello World!"));

app.listen(port, () => console.log(`Example app listening on port ${port}!`));
```

## Generating JWT on the server

We gotta start with things like a JWT-based Authentication and try to validate stuff. [jwt.io](https://go.praveen.science/?redirect=https://jwt.io/) gives you the list of different libraries that support different features of JWT. I tried finding the one that supports everything, but there’s none in JavaScript. ![😔](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f614.png)

Let’s think about what we need here. The backend should be able to support the algorithms HS512 and RS512, as these are recommended by a few banking clients of ours.

### Choosing the right library!

I have planned to use the `jsrsasign`, as that’s the closest to what my backend team generated, and it supports all the algorithms. Let’s include them this way, but don’t forget to install the package locally before you run the code:

```jsx
const JSRSASign = require("jsrsasign");
```

### Implementing the encoding function

The JWT payload is commonly referred as claims — not sure why. So let’s create a `claims` first:

```jsx
const claims = {
  Username: "praveen",
  Password: "Pr@v33n",
  Fullname: "Praveen Kumar"
}
```

That’s everything I need for my application for now from the Users DB. I am not covering any database concepts here, so I am skipping them off. Next is the private key — as the name says, let’s keep it private and not use it in any of our client-side code.

```jsx
const key = "$PraveenIsAwesome!";
```

> **Note:** Keep this thing absolutely secret! ![🤐](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f910.png)

Now we have got our `claims` and `key` ready. Let’s start signing it and generating the token. We have to identify which algorithm we are going to use before signing. These details will be in header. So, let’s create a header.

We will be using the HS512 (HMAC-SHA512) algorithm for signing the token, and we are going to generate a JWT. The other types you can generate or existing standards are:

- JSON Web Signature (JWS): [RFC7515](https://tools.ietf.org/html/rfc7515)
- JSON Web Encryption (JWE): [RFC7516](https://tools.ietf.org/html/rfc7516)
- JSON Web Key (JWK): [RFC7517](https://tools.ietf.org/html/rfc7517)
- JSON Web Algorithms (JWA) – [RFC7518](https://tools.ietf.org/html/rfc7518)
- JSON Web Token (JWT): [RFC7519](https://tools.ietf.org/html/rfc7519)
- JSON Web Key (JWK) Thumbprint: [RFC7638](https://tools.ietf.org/html/rfc7638)
- JWS Unencoded Payload Option: [RFC7797](https://tools.ietf.org/html/rfc7797)
- CFRG Elliptic Curve Signatures (EdDSA): [RFC8037](https://tools.ietf.org/html/rfc8037)

Let’s carry on with the next main process of generating the token. We have got all we need: `header`, `payload` (`claims`), and `key`. We need to stringify the above objects and send to the generator.

```jsx
var sHeader = JSON.stringify(header);
var sPayload = JSON.stringify(claims);
```

The `key` is already a string, so don’t bother stringifying it. To generate the key, we should pass the three strings along with the algorithm to the `JSRSASign.jws.JWS.sign()` function like this:

```jsx
const sJWT = JSRSASign.jws.JWS.sign("HS512", sHeader, sPayload, key);
```

The output you get is a JWT! You can verify the correctness at [jwt.io](https://jwt.io/). Finally, logging the string to the console will get you the output:

```jsx
console.log(sJWT);
```

And when I executed the above code, I got this:

```jsx
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJVc2VybmFtZSI6InByYXZlZW4iLCJQYXNzd29yZCI6IlByQHYzM24iLCJGdWxsbmFtZSI6IlByYXZlZW4gS3VtYXIifQ.nsE9yzUct5vdoNjFZ-2P48vFLGld5-Wr1tne8P3P9eZyCtrRPDSR7dJ8myg30sSV0kcRJVGogzTI92NpOo5pPw
```

Putting it into the online validator along with my signature, I got the same output with a signature-verified message:

![Signature Verified](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/07/signature-verified.jpg?ssl=1)<figcaption>Signature verified.</figcaption>

Woohoo! You can actually check it out [here](https://jwt.io%2F%23debugger-io%3Ftoken%3DeyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJVc2VybmFtZSI6InByYXZlZW4iLCJQYXNzd29yZCI6IlByQHYzM24iLCJGdWxsbmFtZSI6IlByYXZlZW4gS3VtYXIifQ.nsE9yzUct5vdoNjFZ-2P48vFLGld5-Wr1tne8P3P9eZyCtrRPDSR7dJ8myg30sSV0kcRJVGogzTI92NpOo5pPw).

## Decoding and validating JWT

The first step is to validate the token before decoding and getting to know what’s in it. Validation is only necessary to make sure that the token is not tampered with and that it has been signed with the same private key. **This should not be done on the client side.** Let’s try to decode the JSON Web Token by implementing the validation function, and then we will decode it.

### Implementing the validation function

Now that we have successfully generated the token based on the same algorithm my backend team uses, let’s try to validate it and verify that it works. To validate and verify the token, all we need is the `algorithm`, `key`, and the generated `token`. Let’s crack on with this.

```jsx
const token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJVc2VybmFtZSI6InByYXZlZW4iLCJQYXNzd29yZCI6IlByQHYzM24iLCJGdWxsbmFtZSI6IlByYXZlZW4gS3VtYXIifQ.nsE9yzUct5vdoNjFZ-2P48vFLGld5-Wr1tne8P3P9eZyCtrRPDSR7dJ8myg30sSV0kcRJVGogzTI92NpOo5pPw";
const algorithm = "HS512";
const key = "$PraveenIsAwesome!";
```

The syntax is a bit weird — reason being, the validator can try to verify in any of the algorithms, so it takes an array of algorithms. The above information will be passed to the `JSRSASign.jws.JWS.verifyJWT()` function, which takes in the `token`, `key`, and `{"alg": [algorithm]}`, and the syntax is as follows:

```jsx
console.log(
  JSRSASign.jws.JWS.verifyJWT(token, key, {
    alg: [algorithm]
  })
);
```

On the console, when I ran this, I got the following:

```jsx
true
```

Ah, that’s a sweet success. Let us continue to decode the token now. The decoding part is really easy; even a browser on the client side can do it, and that is why my client prefers it for a safe and secure transmission of claims object in a single-page application framework like React.

### Implementing the decoding function

To decode the JSON Web Token, we will be just passing the second part of the token. This contains the payload, or `claims`. We will also be requiring the algorithm, and that can be taken from the first part of the token.

The first thing we need to do is split the token on `.`, then convert it into an array and get the `Header` and `Claim`:

```jsx
const aJWT = sJWS.split(".");
const uHeader = JSRSASign.b64utos(aJWT[0]);
const uClaim = JSRSASign.b64utos(aJWT[1]);
```

Let’s make them `uHeader` and `uClaim` because they are untrusted at this moment. Now let’s parse them. The `JSRSASign.b64utos()` will convert the untrusted Base64 to string, provided by the same library. We’ll now be using the function `JSRSASign.jws.JWS.readSafeJSONString()`, which is similar to `JSON.parse()` but has some more exception handling mechanisms.

```jsx
const pHeader = JSRSASign.jws.JWS.readSafeJSONString(uHeader);
const pClaim = JSRSASign.jws.JWS.readSafeJSONString(uClaim);
```

Now we have got the parsed header and claims. Let’s try to log them and see the output.

```jsx
console.log(pHeader);
console.log(pClaim);
```

Woohoo! We have got the decoded versions here.

```jsx
{
  "alg": "HS512",
  "typ": "JWT"
}
{
  "Username": "praveen",
  "Password": "Pr@v33n",
  "Fullname": "Praveen Kumar"
}
```

Here we go! Now we can access the payload securely (well, at least not in plaintext) this way! ![👍🏻](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f44d-1f3fb.png)

## Complete code and next part

Here’s the complete code that includes signing, generating, validating, verifying, and decoding! ![😇](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f607.png)

```jsx
const JSRSASign = require("jsrsasign");

// Generation
const claims = {
  Username: "praveen",
  Password: "Pr@v33n",
  Fullname: "Praveen Kumar"
};
const key = "$PraveenIsAwesome!";
const header = {
  alg: "HS512",
  typ: "JWT"
};

const sHeader = JSON.stringify(header);
const sPayload = JSON.stringify(claims);
// Generate the JWT
const sJWT = JSRSASign.jws.JWS.sign("HS512", sHeader, sPayload, key);
// Log it to the console.
console.log("JSON Web Token: ", sJWT);

const token =
  "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJVc2VybmFtZSI6InByYXZlZW4iLCJQYXNzd29yZCI6IlByQHYzM24iLCJGdWxsbmFtZSI6IlByYXZlZW4gS3VtYXIifQ.nsE9yzUct5vdoNjFZ-2P48vFLGld5-Wr1tne8P3P9eZyCtrRPDSR7dJ8myg30sSV0kcRJVGogzTI92NpOo5pPw";
const algorithm = "HS512";

// Log it to the console.
console.log(
  "Verification: ",
  // Validation
  JSRSASign.jws.JWS.verifyJWT(token, key, {
    alg: [algorithm]
  })
);

// Decoding
const sJWS = token;
const aJWT = sJWS.split(".");
const uHeader = JSRSASign.b64utos(aJWT[0]);
const uClaim = JSRSASign.b64utos(aJWT[1]);
const pHeader = JSRSASign.jws.JWS.readSafeJSONString(uHeader);
const pClaim = JSRSASign.jws.JWS.readSafeJSONString(uClaim);
// Decoded objects.
// Log it to the console.
console.log("Header: ", pHeader);
console.log("Claim: ", pClaim);
```

The above code will give you an output like this:

```jsx
➜  MockAPIServer node dec-enc.js
JSON Web Token:  eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJVc2VybmFtZSI6InByYXZlZW4iLCJQYXNzd29yZCI6IlByQHYzM24iLCJGdWxsbmFtZSI6IlByYXZlZW4gS3VtYXIifQ.nsE9yzUct5vdoNjFZ-2P48vFLGld5-Wr1tne8P3P9eZyCtrRPDSR7dJ8myg30sSV0kcRJVGogzTI92NpOo5pPw
Verification:  true
Header: { alg: 'HS512', typ: 'JWT' }
Claim: { Username: 'praveen',
  Password: 'Pr@v33n',
  Fullname: 'Praveen Kumar' }
```

By the way, what I have done is just a server-side generation component and doesn’t include the “web server” to send you the token using a POST request.

Now that we have completed our work on the server side, let’s start building the REST API endpoints for the client to consume. Keep an eye out for part two — coming soon!
* * *
## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [Creating a full-stack MERN app using JWT authentication: Part 1](https://blog.logrocket.com/mern-app-jwt-authentication-part-1/) appeared first on [LogRocket Blog](https://blog.logrocket.com).