I spent weeks building auth for every project. So I packaged it once.
If you've built more than two backend projects with NestJS, you already know the drill.
Every time you start something new — a SaaS, a client project, a side business — you end up writing the same things:
- Email + password login
- JWT access tokens and refresh tokens
- OAuth with Google (and the edge case where the user already has an account with that email)
- Password recovery via OTP
- Session tracking and revocation
- 2FA setup and verification
You've done it before. You'll do it again. And every time you do, it takes 2–3 weeks minimum if you want to get it right.
I got tired of that loop. So I packaged everything into one boilerplate I actually use myself.
What I built
Advanced Auth Fullstack Kit v3.0 is a production-ready authentication system built with:
- Backend: NestJS · TypeScript · PostgreSQL · Prisma · Redis · Passport.js · Argon2 · Swagger
- Frontend: Next.js · TypeScript · Tailwind CSS · Shadcn/UI · TanStack Query · React Hook Form · Zod
- Services: Cloudinary (avatar uploads) · Resend (transactional email)
- Infrastructure: Docker (dev + production) · multi-schema Prisma · HttpOnly cookies
The features that took the longest to get right
Refresh Token Rotation
This is the part most tutorials skip or get wrong.
The naive approach: issue a long-lived JWT and call it a day. The problem: if that token gets stolen, the attacker has access until it expires — and you can't do anything about it.
The right approach: short-lived access tokens (15 minutes) + long-lived refresh tokens that rotate on every use. Each time the client uses a refresh token, it gets invalidated and a new one is issued. If a stolen token is used, the rotation detects a reuse attempt and revokes the entire session family.
Instant Session Revocation
Standard JWTs are stateless — once issued, they're valid until they expire. That means even if a user logs out or you delete their session from the DB, the access token still works.
The kit solves this by validating every access token against an active session in the database. If the session doesn't exist (deleted, revoked, or expired), access is denied immediately — no waiting for JWT expiry.
Yes, this adds one DB lookup per request. In practice, for most applications, that's negligible — and the security tradeoff is worth it.
Session Management UI
Users can see every active session — device, IP, location, last activity — and revoke any of them individually. This is the kind of feature you see in Google or GitHub account settings. It's not hard to build, but it's one of those things that takes a full day to wire up properly.
Multi-Provider OAuth Account Linking
The edge case that trips everyone up: a user registers with their email, then tries to sign in with Google using the same address. Most implementations create a duplicate account. This kit links both methods to the same profile, so the user has a single account regardless of how they authenticate.
2FA with TOTP
Compatible with Google Authenticator, Authy, and any standard TOTP app. The flow covers enabling 2FA, generating a QR code, verifying the setup, and handling login with the second factor — including recovery flows.
Architecture decisions worth noting
Prisma Multi-Schema — the database is split into logical schemas (auth, user, sessions) to keep concerns separated as the project scales.
Server-side avatar uploads via Cloudinary signatures — the backend generates a signed upload URL, the frontend uploads directly to Cloudinary. This keeps the server out of the image pipeline while maintaining control over who can upload.
OTP via Redis with TTL — password recovery codes are stored in Redis with automatic expiration. No cleanup jobs, no stale records.
Modular NestJS structure — each domain (auth, sessions, profile, account) is its own module with its own guards, interceptors, and DTOs. You can extend or replace any part without touching the rest.
What you get
- Complete NestJS backend source
- Complete Next.js frontend source
- Docker configuration for dev and production
-
.envexample files for all services - Swagger documentation at
/api/docs - Step-by-step setup tutorial
Why I'm sharing this
I'm building this in public. The kit is on Gumroad — it's a paid product, and I'll be honest about that.
But most of what I write here will be the actual technical content behind it: how each piece works, what I got wrong the first time, and how I ended up with the current implementation.
If you're building auth in NestJS and Next.js, I hope some of it is useful — whether you use the kit or not.
Demo video → YouTube
Kit on Gumroad → Advanced Auth Fullstack Kit v3.0
My site → ivnoff.vercel.app
Tags: nestjs nextjs typescript webdev security


Top comments (0)