This library is in early development. Expect breaking changes.
Core Concepts

Security & Caveats

What is enforced where, and what you should not assume.

Client redirects are not security

Client-side redirects improve UX but don't prevent unauthorized access. Always validate on the server.

CSRF / origin checks

Better Auth performs origin checks for cookie-based requests (it validates Origin / Referer). If you use multiple domains (custom domains, preview URLs, etc.), add them to trustedOrigins in your auth config.

server/auth.config.ts
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'

export default defineServerAuth({
  trustedOrigins: [
    'http://localhost:3000',
    'https://your-domain.com',
    'https://your-preview.workers.dev',
  ],
})
If you deploy preview environments, you must include the preview origin in trustedOrigins. Otherwise, sign-in or sign-up requests can fail origin validation even when the API endpoint is healthy.

API enforcement behavior

The built-in Nitro middleware only checks routeRules.auth for /api/**.

Customizing Unauthorized Behavior

By default, unauthorized requests to protected routes receive a 401 response. To customize:

Redirect to login instead of 401:

server/middleware/auth.ts
import { sendRedirect } from 'h3'

export default defineEventHandler(async (event) => {
  const session = await getUserSession(event)
  if (!session && event.path.startsWith('/api/protected')) {
    return sendRedirect(event, '/login', 302)
  }
})

Return JSON error for API routes:

// This is the default behavior for /api/* routes
throw createError({
  statusCode: 401,
  data: { error: 'Authentication required' }
})

If you want different behavior (e.g. enforce auth: 'user' for APIs), add your own Nitro middleware and/or call requireUserSession(event) directly inside handlers.

server/api/secret.get.ts
export default defineEventHandler(async (event) => {
  await requireUserSession(event)
  return { ok: true }
})

Default login route

Unauthenticated users are redirected to /login when a page requires auth. To use another path, set redirectTo on the protected route rule (or page meta auth object).

If your redirectTo target does not exist, users will be redirected to a 404 page. Ensure redirect targets are valid app routes.

Rate limiting

This module does not include built-in rate limiting. Authentication endpoints can be targeted by brute force attacks.

Recommendations:

  • Use Cloudflare rate limiting rules
  • Implement server middleware with Redis-backed rate limiting
  • Configure your reverse proxy (nginx, Caddy) to limit requests

DevTools in production

DevTools are automatically disabled when NODE_ENV=production. The /api/_better-auth/* endpoints and devtools page are never registered in production builds.