Next.js Scaffold (Custom)

A Next.js App Router application with custom OAuth and email authentication using API routes and middleware. This scaffold implements all auth flows from scratch — no SDK required.


Overview

This scaffold shows how to integrate AuthGate into a Next.js app using the App Router. It uses the same auth patterns as the React scaffold but adapted for Next.js conventions: API route handlers, middleware-based route protection, and the async cookies() API.

What's included:

  • Next.js 16 with App Router
  • API route handlers for OAuth callback and email auth
  • Middleware-based protection for /dashboard routes
  • HMAC-signed session cookies with timing-safe comparison
  • Nonce-based OAuth state validation
  • Route groups for (auth) and (protected) layouts
  • Environment validation with @t3-oss/env-nextjs

Prerequisites

  • Node.js 18+
  • An AuthGate project with at least one provider enabled
  • An API key from the AuthGate dashboard
  • A registered callback URL pointing to /api/auth/callback

Setup

cd apps/scaffolds/nextjs/custom
cp .env.example .env
# Fill in your AuthGate credentials
pnpm install
pnpm dev

The dev server runs at http://localhost:3002.


Directory structure

src/
├── app/
│   ├── layout.tsx
│   ├── page.tsx                        # Home page
│   ├── (auth)/
│   │   ├── layout.tsx                  # Auth pages layout
│   │   ├── login/page.tsx
│   │   ├── signup/page.tsx
│   │   ├── forgot-password/page.tsx
│   │   └── reset-password/page.tsx
│   ├── (protected)/
│   │   └── dashboard/page.tsx
│   └── api/
│       └── auth/
│           ├── callback/route.ts       # OAuth callback handler
│           └── email/
│               ├── signup/route.ts
│               ├── signin/route.ts
│               ├── forgot-password/route.ts
│               └── reset-password/route.ts
├── lib/
│   ├── session.ts                      # HMAC-signed cookie helpers
│   ├── oauth-state.ts                  # State creation + verification
│   └── authgate.ts                     # Token verification
├── env.ts                              # t3-oss env validation
└── middleware.ts                        # Route protection

Key files

src/lib/session.ts

Manages HMAC-signed session cookies using the Next.js cookies() API:

  • getSession() — reads and verifies the session cookie, returns the user or null
  • setSession(user) — signs and sets the session cookie (7-day expiry)
  • clearSession() — deletes the session cookie

The session format is JSON.signature where the signature is HMAC-SHA256 with timing-safe comparison on verification.

src/lib/oauth-state.ts

Creates and verifies HMAC-signed OAuth state parameters:

  • createState(nonce) — returns nonce.timestamp.hmac_signature
  • verifyState(state, nonce) — checks nonce match, 10-minute TTL, and HMAC signature

Both functions use timing-safe comparison to prevent timing attacks.

src/app/api/auth/callback/route.ts

The OAuth callback handler:

  1. Reads token and state from query params
  2. Retrieves the stored nonce from cookie
  3. Verifies state (nonce + timestamp + HMAC)
  4. Verifies the JWT with AuthGate's /api/v1/token/verify
  5. Sets the session cookie and redirects to /dashboard

src/middleware.ts

Protects /dashboard routes by checking for a valid session cookie. Redirects unauthenticated users to /login.

Differences from the React scaffold

AspectReact (Hono)Next.js
ServerHono + Node.jsNext.js API routes
Route protectionReact component (AuthGuard)Next.js middleware
Cookie APIhono/cookie helpersnext/headers cookies()
Env validationManual (Zod)@t3-oss/env-nextjs
Route groupsReact Router(auth) / (protected)

Environment variables

VariableServer/ClientDescription
AUTHGATE_URLServerAuthGate API base URL
AUTHGATE_API_KEYServerAPI key for token verification
STATE_SECRETServerMin 32 characters, used for HMAC signing
NEXT_PUBLIC_APP_URLClientYour app's URL (e.g. http://localhost:3002)

Was this page helpful?