full stack

Secure Advanced Auth Engine

Production-grade full-stack authentication with zero client-side XSS token surface, CSRF double-submit hardening, and automatic breach containment.
RoleFull-Stack Engineer
Timeline2025
Categoryfull stack
Stack7 technologies
NestJSReact.jsMongoDBDockerJWT SecurityAtomic DesignCSRF Protection
Overview

Project Overview

The Secure Advanced Auth Engine is a full-stack authentication reference implementation that goes beyond the standard JWT tutorial pattern. The NestJS backend enforces a strict token strategy — short-lived access tokens are stored only in memory on the client, while long-lived refresh tokens travel exclusively in HttpOnly, SameSite=Strict cookies — eliminating the two most common client-side token theft vectors. The React frontend is built to the Atomic Design specification, making the component architecture as well-structured as the security model.


Capabilities

Key Features

  • In-Memory Access Token Storage

    Access tokens are held in a JavaScript closure on the client, never written to localStorage or sessionStorage, removing the entire localStorage-based XSS exfiltration surface.

  • HttpOnly Refresh Token Cookies

    Refresh tokens are issued as HttpOnly, Secure, SameSite=Strict cookies. JavaScript cannot read them, and they are not sent on cross-origin requests, neutralising both XSS and CSRF theft.

  • Session Breach Containment

    A custom token family mechanism detects refresh token reuse — a strong indicator of token theft — and immediately invalidates the entire session family across all devices.

  • CSRF Double-Submit Protection

    A CSRF token is generated per session, embedded in a non-HttpOnly cookie and verified as a custom request header, providing robust protection against cross-site request forgery without server-side state.


Engineering

Technical Architecture

  1. NestJS Guard pipeline: every protected route passes through JwtAuthGuard (validates access token) and CsrfGuard (validates double-submit token) before reaching the controller.
  2. MongoDB with Mongoose stores hashed refresh token families per user, enabling O(1) revocation lookups without a Redis dependency for this use case.
  3. Silent token refresh: the React client registers an Axios response interceptor that automatically retries failed 401 responses after silently refreshing the access token, transparent to the rest of the application.
  4. Docker Compose orchestrates the NestJS API, React client (served via Nginx), and MongoDB instance with a shared private network, mapping only the Nginx port to the host.
  5. Atomic Design component hierarchy on the frontend (Atoms → Molecules → Organisms → Templates → Pages) mirrors the backend's modular NestJS folder structure for conceptual consistency.

Security Design

The Token Strategy

Most JWT implementations make one of two mistakes: they store tokens in localStorage (trivially readable by any injected script) or they rely solely on cookies without addressing CSRF. This project treats both as first-class threats and designs the token lifecycle around eliminating both simultaneously.

Access Tokens Live in Memory Only

The access token is issued as a short-lived JWT (15 minutes) and held in a JavaScript module-level variable — never in localStorage, sessionStorage, or a cookie. It exists only for the lifetime of the browser tab. When the tab closes, the token is gone. This makes it invisible to XSS attacks that try to exfiltrate credentials through document.cookie or localStorage reads.

Refresh Tokens Are Never Readable by JavaScript

The long-lived refresh token (7 days) lives exclusively in an HttpOnly, Secure, SameSite=Strict cookie set by the server. JavaScript cannot read it. The SameSite=Strict attribute means the browser will not attach it to any cross-origin request, which eliminates CSRF as a refresh token theft vector even without the double-submit pattern.

Threat Response

Session Breach Containment

Token rotation alone is not enough. If an attacker steals a refresh token and uses it before the legitimate user does, the server has no way to know which party is the attacker. The token family mechanism solves this by treating a reused refresh token as definitive evidence of a breach.

How the Family Mechanism Works

Every issued refresh token belongs to a family identified by a UUID. When a refresh token is used, the server issues a new token in the same family and marks the old one as consumed. If a consumed token is ever presented again — which only happens if someone copied the old token — the server immediately invalidates every token in that family across all devices, forcing a full re-authentication. The legitimate user is inconvenienced for a moment; the attacker loses all access permanently.

React & Atomic Design

Frontend Architecture

The React client is structured according to Brad Frost's Atomic Design methodology: Atoms (buttons, inputs, labels) compose into Molecules (form fields with validation), which combine into Organisms (the login form, the registration flow), assembled into Templates (the auth page shell), and finally instantiated as Pages. This discipline keeps the component tree shallow, makes each layer independently testable, and mirrors the modular structure of the NestJS backend.

Silent Token Refresh Flow

Because access tokens live in memory and expire every 15 minutes, the client needs a way to refresh them transparently. An Axios response interceptor catches any 401 response, pauses the failed request, fires a refresh call to the /auth/refresh endpoint (which sends the HttpOnly cookie automatically), receives a new access token, stores it in memory, and replays the original request — all invisible to the component that made the original call.

Results

Impact & Outcomes

  • ZeroXSS Token Surface
  • 2 / 2CSRF Vectors Covered
  • Full family revocationBreach Containment
  • 1 commandDeploy Complexity

Takeaways

Lessons Learned

  • Security architecture decisions compound: choosing in-memory token storage forces you to solve the silent-refresh problem, which in turn teaches you about token rotation and reuse detection.
  • The Atomic Design system pays dividends on a security-focused project because it keeps visual concerns cleanly separated from auth state logic.
  • Docker Compose is the right tool for a multi-service development and demo environment; switching to Kubernetes would be premature optimisation for a project at this scale.
  • Refresh token reuse detection is a simple MongoDB upsert operation but delivers enterprise-level session security — the payoff-to-complexity ratio is exceptional.