A primitive authentication architecture for Next.js 15 (App Router). Designed to mitigate race conditions during JSON Web Token (JWT) rotation in highly concurrent Client/Server boundaries, ensuring zero hydration mismatches and strict Edge-native verification.
In modern SSR/SPA applications, access token expiration introduces a critical race condition. If an expired token triggers N concurrent API requests (e.g., parallel data fetching in a dashboard), the backend will return N 401 Unauthorized responses.
Standard fetch wrappers handle this poorly by either:
- Triggering
Nredundant refresh requests (causing database locks or invalidating rotating refresh tokens). - Forcing an immediate client-side redirect, destroying the user's current UI state.
This pipeline intercepts network requests at the fetcher level, implementing a Mutex (Mutual Exclusion) Lock to pause concurrency during the refresh lifecycle.
sequenceDiagram
participant C as Client (customFetch)
participant Q as Mutex Queue
participant A as Next.js API (/refresh)
participant R as Resource API
C->>R: Request 1 (Expired Access Token)
C->>R: Request 2 (Expired Access Token)
R-->>C: 401 Unauthorized (Req 1)
rect rgb(30, 30, 30)
Note over C, Q: Mutex Lock Activated (isRefreshing = true)
C->>A: POST /api/auth/refresh
R-->>C: 401 Unauthorized (Req 2)
C->>Q: Freeze Req 2 (Push to Queue)
end
A-->>C: 200 OK (New Tokens in HttpOnly Cookies)
rect rgb(30, 30, 30)
Note over C, Q: Mutex Lock Released (isRefreshing = false)
C->>R: Retry Request 1 (New Token)
Q->>R: Resolve & Retry Request 2 (New Token)
end
R-->>C: 200 OK
Edge-First Verification: Route protection (proxy.ts) leverages jose to validate symmetric HS256 signatures directly at the Edge. Bypasses the Node runtime entirely for sub-5ms latency proxying.
Fail-Fast Bootstrapping: Application lifecycle strictly requires JWT_SECRET at initialization. Auto-generation fallbacks are disabled to prevent silent session invalidation across orchestrator restarts.
Server Actions (React 19): Authentication boundaries (Login/Logout mutations) are strictly handled via Server Actions ("use server"), bypassing client-side JavaScript execution for payload submission.
Cookie Strictness: All state tokens (access_token, refresh_token) operate strictly under HttpOnly, Secure, and SameSite=lax constraints.
- Framework: Next.js 15 (App Router + Turbopack)
- Language: TypeScript (Strict mode enabled, zero-
anypolicy) - Cryptography:
jose(Edge-compatible runtime) - Validation:
zod - Package Manager: pnpm
Clone and install dependencies:
pnpm installSet environment variables (.env.local):
JWT_SECRET="your_cryptographically_secure_string_here"Boot the Turbopack server:
pnpm dev