• Mail us
  • Book a Meeting
  • Call us
  • Chat with us

NodeJS

How to Implement Double JWT Authentication for Secure Web Applications


Introduction

Double JWT certification is a safety mechanism that increases user authentication by employing two types of JSON web tokens (JWTS): an access token and a refresh token. This approach balances users by limiting the access token lifespan by limiting safety and user experience, while users allow them to refresh them originally.

Why Use Double JWT Authentication?

  1. Security: Short-lived access tokens reduce the risk of token misuse if compromised.

  2. User Experience: Long-lived refresh tokens minimize frequent logins.

  3. Scalability: Stateless authentication enables distributed architectures.

  4. Control: Refresh token invalidation allows session revocation without relying on access tokens.

Key Components

  1. Access Token:

    • Short lifespan (e.g., 15 minutes).

    • Used for authenticating API requests.

    • Typically stored in memory or secure HTTP-only cookies.

  2. Refresh Token:

    • Long lifespan (e.g., 7 days or more).

    • Used to obtain new access tokens without requiring user credentials.

    • Stored securely in HTTP-only cookies or databases.

Authentication Flow

  1. User Login:

    • The server validates user credentials and issues an access token and a refresh token.

  2. Accessing Protected Routes:

    • The user includes the access token in API requests.

    • The server verifies the token and grants access.

  3. Token Expiry Handling:

    • If an access token gets expires, the client uses the refresh token to request a fresh new token

    • The server then verifies the refresh token and issues a new access token.

  4. Logout & Revocation:

    • Users log out, and refresh tokens are removed from storage.

    • The server can blacklist refresh tokens if needed.

Implementation Considerations

  • Token Storage: Securely store access tokens in memory and refresh tokens in HTTP-only cookies or databases.

  • Blacklist Mechanism: Implement a mechanism to revoke refresh tokens if necessary.

  • Token Rotation: Issue new refresh tokens with each refresh request to prevent misuse.

  • Secure Transmission: Always use HTTPS to protect token exchanges.

JWT Strategy Example

Access Token Strategy

import { Injectable } from '@nestjs/common';import { PassportStrategy } from '@nestjs/passport';import { ExtractJwt, Strategy } from 'passport-jwt';@Injectable()export class JwtAccessStrategy extends PassportStrategy(Strategy, 'jwt') { constructor() {   super({     jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),     secretOrKey: process.env.JWT_ACCESS_SECRET,   }); } async validate(payload: any) {   return { userId: payload.sub, email: payload.email }; }}

 

Refresh Token Strategy

import { Injectable, UnauthorizedException } from '@nestjs/common';import { PassportStrategy } from '@nestjs/passport';import { ExtractJwt, Strategy } from 'passport-jwt';import { Repository } from 'typeorm';import { InjectRepository } from '@nestjs/typeorm';import { User } from '../entities/user.entity';import * as bcrypt from 'bcrypt';@Injectable()export class JwtRefreshStrategy extends PassportStrategy(Strategy, 'jwt-refresh') { constructor(   @InjectRepository(User) private userRepository: Repository<User> ) {   super({     jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),     secretOrKey: process.env.JWT_REFRESH_SECRET,     passReqToCallback: true,   }); } async validate(req, payload: any) {   const refreshToken = req.headers.authorization.split(' ')[1];   const user = await this.userRepository.findOne({ where: { id: payload.sub } });   if (!user || !(await bcrypt.compare(refreshToken, user.refreshToken))) {     throw new UnauthorizedException();   }   return user; }}

Ready to transform your business with our technology solutions?   Contact Us today to Leverage Our NodeJS Expertise.

Share

facebook
LinkedIn
Twitter
Mail
NodeJS

Related Center Of Excellence