Logo

Command Palette

Search for a command to run...

Authentication

Deep dive into the centralized auth flow, sessions, and secure cookies.

The starter uses a Centralized Authentication Architecture where all authentication logic is handled by the Node/Express backend.

Unified Auth Flow

  • Secure Login: Users register or log in using an OTP (One-Time Password) or Magic Link sent to their email.
  • Resend Integration: All emails are dispatched securely via the Resend API.
  • Session Dispatch: Upon successful login, the API issues a secure, HttpOnly cookie containing the session ID.

Centralized Session Management

Authentication relies entirely on the Node/Express backend for security, effectively eliminating fragmented logic.

1. The Proxy Rewrite

The Next.js frontend is configured to natively proxy GET /api/* requests over to the Express server using next.config.ts. This allows the frontend to communicate with the API without CORS issues.

// apps/web/next.config.ts
const nextConfig = {
  async rewrites() {
    return [
      {
        source: "/api/:path*",
        destination: "http://localhost:4000/:path*",
      },
    ];
  },
};

2. Zustand Sessions

The Next.js AuthGuard queries /api/v1/auth/session to retrieve the securely decrypted user state. This state is then managed by a Zustand store on the client side.

  • Security: No JWTs are exposed directly to client interceptors.
  • Persistence: Sessions are maintained through secure cookies that are automatically sent with every request to the API.

Secure Cookies

Because the application secures authentication using HttpOnly Cookies, your domain setup must respect COOKIE_DOMAIN.

Local Development

Localhost handles this gracefully, allowing the frontend and API to share cookies on localhost:3000 and localhost:4000.

Production Domain Strategy

In production, both your UI (app.yourdomain.com) and your API (api.yourdomain.com) must align beneath a permissive cookie domain (.yourdomain.com).

  • Cookie Name: session_id
  • Domain: .yourdomain.com
  • Path: /
  • SameSite: Lax (or None if cross-site is required)
  • Secure: true
  • HttpOnly: true