JWT Explained: Structure, Flow, and Implementation with Hapi.js

2 min read
Cover Image for JWT Explained: Structure, Flow, and Implementation with Hapi.js

JWT, or JSON Web Token, is a compact and secure way to transmit information between a client and a server as a JSON object. It’s commonly used for authentication in web applications, allowing users to log in and access protected resources. A JWT consists of three parts: a header (which specifies the token type and signing algorithm), a payload (which contains user data and claims), and a signature (which ensures the token’s integrity). Once issued, the token can be sent with each request, and the server can verify it without needing to store session data.

Brief Flow

  1. User logs in → server provides an access token & refresh token.

  2. Client stores both tokens.

  3. Client uses the access token to request the API.

  4. If the access token expires → client uses the refresh token to request a new one.

  5. If the refresh token expires → user must log in again (user is logged out).

Structure

Code with hapi.js

To use JWT in your Hapi.js project, first install the @hapi/jwt package—it provides the tools needed to generate and verify tokens.

npm install @hapi/jwt

const Jwt = require('@hapi/jwt');

const TokenManager = {
  generateAccessToken: (payload) => Jwt.token.generate(payload, process.env.ACCESS_TOKEN_KEY),
  generateRefreshToken: (payload) => Jwt.token.generate(payload, process.env.REFRESH_TOKEN_KEY),
};

module.exports = TokenManager;

Header

Automatically generated by the Hapi.js JWT library.

Payload

This is the data you pass when generating the token.

Signature

Created using a secure secret key stored in your environment variables. Example command to generate the key:

require('crypto').randomBytes(64).toString('hex');

Generates a secure, random 128-character hexadecimal string by first importing the built-in crypto module, then creating 64 bytes of cryptographically strong random data, and finally converting that data into a hexadecimal format.

Example .env values:

ACCESS_TOKEN_KEY=e4eef8adf135cb98d98893342fd8d76d5ea819c2f5073aca3580f55a5f30c8d9acd2bb7f64ea92d35538ad4296799c4baaf6bf1c45b6c39e2034fd86ea19efd9 REFRESH_TOKEN_KEY=b1d3967b973929d0174cfb5d3b7fe16315bb488ed85d7016cc556cebce41b80120754fd3d3e56319117a4b5500b7897085ee7e11217d6a4c960214027882668b

Final Thoughts

JWT offers a powerful and efficient way to handle authentication in modern web applications. By understanding its structure—header, payload, and signature—and how access and refresh tokens work together, developers can build secure, scalable systems without relying on server-side sessions. With tools like Hapi.js and secure key generation via Node.js, implementing JWT becomes both practical and robust. Keep your keys safe, your tokens short-lived, and your users protected.