JSON Web Tokens (JWT): Safe Online and Mobile Authentication and Authorisation

Kimtai Developer
4 min readJul 26, 2024

--

You can find me on Upwork for React tasks, work or assignment — https://www.upwork.com/freelancers/denniskiprotichk and Github — https://github.com/kimtaidennis

Introduction

In the realm of web development and modern digital space, authentication and protection of web resources is of great importance. Developers must ensure all aspects of web security are adhered to enhance data integrity and handling of user interactions.

JWTs have emerged as one of the best solutions that developers can use to enhance security and authentication of web and mobile apps. In this article, we will highlight some of the key aspects and a simple implementation of JWTs on a Node app.

What is JSON Web Token (JWT)?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Structure of a JWT

In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:

Header

The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA.

{
"alg": "HS256",
"typ": "JWT"
}

Payload

Payload contains the claims. These are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.

{
"sub": "user123",
"name": "John Doe",
"admin": true
}

Signature

Signature part is created by taking the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)

When should you use JSON Web Tokens?

  1. Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token.
  2. Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed — for example, using public/private key pairs — you can be sure the senders are who they say they are.

Example

In this article, we will use node.js as our framework for explaining the JWT implementation. We will requires jsonwebtoken library which provides utilities for generating and verifying JWTs.

npm install jsonwebtoken cookie-parser dotenv
// Import required libraries
const jwt = require('jsonwebtoken');
// Required to provide ACCESS_TOKEN_SECRET & REFRESH_TOKEN_SECRET
// these SECRET keys can be generated on terminal in node environment by using below command
// require('crypto').randonBytes(64).toString('hex)
require('dotenv').config()

const signinUser = async (req,res) => {

// get form data
const { email,pwd } = req.body

// status 400 bad request
if( !email || !pwd ) return res.status(400).json({ message: 'Username and password required!!'})

try {
const foundUser = usersDB.users.find( el => el.email === email)
if(!foundUser) return res.status(401).json({ message: 'Email or Password invalid'})

const pwdCheck = await bcrypt.compare(pwd, foundUser.pwd)
if(!pwdCheck) return res.sendStatus(401)

const accessToken = jwt.sign(
{ email: foundUser.email },
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: '45s'}
)

const refreshToken = jwt.sign(
{ email: foundUser.email },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: '1d'}
)

res.cookie('jwt', refreshToken, { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 }) //sameSite: 'None' secure: true
return res.status(200).json({ message: 'SignIn successfull', email: foundUser.email, token: accessToken })

} catch (error) {
return res.status(500).json({ message: error.message })
}
}


// refresh token to provide new access token once old access token expires
const refreshToken = async (req,res) => {

const cookies = req.cookies;

// Bad Request
if( !cookies?.jwt ) return res.sendStatus(401);
const refreshToken = cookies.jwt;

// Check user by token
const foundUser = usersDB.users.find( el => el.token === refreshToken)

// Conflict username
if(!foundUser) return res.sendStatus(403)

jwt.verify(
refreshToken,
process.env.REFRESH_TOKEN_SECRET,
(err, decoded) => {
if(err || foundUser.email !== decoded.email ) return res.sendStatus(403) // invalid token
const accessToken = jwt.sign(
{ email: decoded.email },
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: '45s'}
);
res.json({ accessToken })
}
)
}

The above methods show how to implement a simple authentication backend to generate and verify JWTs.

JSON Web Tokens (JWT) are a powerful and flexible tool for secure authentication and data exchange between parties. Their simplicity and security make them an ideal choice for modern web applications.

Github

you can get the code in this repo: https://github.com/kimtaidennis/node-user-jwt.

--

--

Kimtai Developer

I am a react dev with a strong foundation in Typescript and Tailwindcss, and a knack for creating intuitive and amazing user experiences.