Auth in NestJS: Why I Didn't Use Clerk

A technical deep-dive on self-hosted auth with Passport.js, JWT refresh token rotation, and one-time OAuth code exchange.

nestjsauthsecuritytechnical

When I started building NestForge Pro, the first big decision was auth. Use a managed service like Clerk or Auth0, or build it yourself?

The Research

I looked at 7 paid NestJS boilerplates. 6 of 7 use self-hosted auth. The reason is simple: developers buying a NestJS SaaS starter kit want to own their auth stack. They're choosing NestJS over Next.js precisely because they want backend control.

Refresh Token Rotation

The core of the auth system is JWT access tokens with refresh token rotation. Here's what makes it secure:

Token Flow

1. User logs in → receives access token (15min) + refresh token (7 days)

2. Access token expires → client sends refresh token

3. Server verifies refresh token, issues new pair, invalidates old refresh token

4. If an old refresh token is reused → all tokens for that user are revoked

The Security Detail

Refresh tokens are hashed with bcrypt before storage. Not stored in plain text. If your database leaks, the attacker can't use the refresh tokens.

One-Time Auth Code Exchange

The OAuth flow has a subtle security fix. Instead of putting tokens in the redirect URL (where they end up in browser history, server logs, and referrer headers), I use a one-time auth code:

1. Google OAuth callback → server generates a random code

2. Code is stored in Redis with a 60-second TTL

3. Client exchanges code for tokens via a POST request

4. Code is deleted immediately after use

Tokens never touch the URL bar.

Magic Links

Passwordless login via email. The flow:

1. User enters email → server generates a signed token

2. Token is sent via email with a 15-minute expiry

3. User clicks link → token is verified → session is created

Why Passport.js in 2026

Passport.js is old. It's also battle-tested, has strategies for everything, and integrates cleanly with NestJS guards. For a SaaS starter that needs to support JWT, Google OAuth, and magic links — Passport is still the right call.

The full auth system ships with [NestForge Pro](https://nestforge.dev) — JWT + refresh rotation + Google OAuth + magic links + team invites, all integrated.