View as Json

JWT Utils Function

JWT Utils Function provides a production-ready authentication utility based on access tokens and refresh tokens for Express-based applications.


Installation Guide

Install the component using the servercn CLI:

npx servercn-cli add jwt-utils

Prerequisites

Ensure the following environment variables are defined before running the application:

JWT_ACCESS_SECRET = "your-access-secret";
JWT_REFRESH_SECRET = "your-refresh-secret";

JWT_ACCESS_SECRET: Used to sign and verify access tokens

JWT_REFRESH_SECRET: Used to sign and verify refresh tokens - These secrets must be different and kept private

src/configs/env.ts
import "dotenv-flow/config";
import { z } from "zod";
 
export const envSchema = z.object({
  NODE_ENV: z
    .enum(["development", "test", "production"])
    .default("development"),
 
  PORT: z.string().regex(/^\d+$/, "PORT must be a number").transform(Number),
 
  LOG_LEVEL: z
    .enum(["fatal", "error", "warn", "info", "debug", "trace"])
    .default("info"),
  
  JWT_REFRESH_SECRET: z.string().nonempty("JWT_REFRESH_SECRET is required"),
  JWT_ACCESS_SECRET: z.string().nonempty("JWT_ACCESS_SECRET is required"),
});
 
export type Env = z.infer<typeof envSchema>;
 
const result = envSchema.safeParse(process.env);
 
if (!result.success) {
  console.error("❌ Invalid environment configuration");
  console.error(z.prettifyError(result.error));
  process.exit(1);
}
 
export const env: Readonly<Env> = Object.freeze(result.data);
 
export default env;

Basic Implementation

src/utils/jwt.ts
import jwt from "jsonwebtoken";
import env from "../configs/env";
 
const ACCESS_TOKEN_EXPIRY = "15m";
const REFRESH_TOKEN_EXPIRY = "7d";
 
// Generate a short-lived access token
export function generateAccessToken(user: { _id: string }) {
  return jwt.sign({ _id: user._id }, process.env.JWT_ACCESS_SECRET!, {
    expiresIn: ACCESS_TOKEN_EXPIRY
  });
}
 
// Generate a long-lived refresh token
export function generateRefreshToken(userId: string) {
  return jwt.sign({ userId }, process.env.JWT_REFRESH_SECRET!, {
    expiresIn: REFRESH_TOKEN_EXPIRY
  });
}
 
// Verify and decode an access token
export function verifyAccessToken(token: string) {
  return jwt.verify(token, process.env.JWT_ACCESS_SECRET!) as {
    _id: string;
  };
}
 
// Verify and decode a refresh token
export function verifyRefreshToken(token: string) {
  return jwt.verify(token, process.env.JWT_REFRESH_SECRET!) as {
    userId: string;
  };
}

Usage Example

import {
  generateAccessToken,
  generateRefreshToken,
  verifyAccessToken
} from "../utils/jwt";
 
export async function issueTokens(userId: string) {
  // Short-lived token used for authorization
  const accessToken = generateAccessToken({ _id: userId });
 
  // Long-lived token used to refresh sessions
  const refreshToken = generateRefreshToken(userId);
 
  return { accessToken, refreshToken };
}
 
export async function decodeAccessToken(token?: string) {
  // If no token is provided, deny access immediately
  if (!token) {
    throw ApiError.unauthorized("Access token missing");
  }
 
  // jwt.verify throws if the token is invalid or expired
  const payload = verifyAccessToken(token);
 
  // Payload contains the user id
  return payload._id;
}

File & Folder Structure

Loading files...

Installation

npx servercn-cli add jwt-utils