auth0-nuxt
Use when implementing Auth0 authentication in Nuxt 3/4 applications, configuring session management, protecting routes with middleware, or integrating API access tokens - provides setup patterns, composable usage, and security best practices for the @auth0/auth0-nuxt SDK
Auth0 Nuxt SDK
Overview
Server-side session authentication for Nuxt 3/4. NOT the same as @auth0/auth0-vue (client-side SPA).
Core principle: Uses server-side encrypted cookie sessions, not client-side tokens.
When to Use
Use this when:
- Building Nuxt 3/4 applications with server-side rendering (Node.js 20 LTS+)
- Need secure session management with encrypted cookies
- Protecting server routes and API endpoints
- Accessing Auth0 Management API or custom APIs
Don't use this when:
- Using Nuxt 2 (not supported - use different Auth0 SDK)
- Building pure client-side SPA without server (use @auth0/auth0-vue instead)
- Using non-Auth0 authentication provider
- Static site generation only (SSG) without server runtime
Critical Mistakes to Avoid
| Mistake | Solution |
|---|---|
Installing @auth0/auth0-vue or @auth0/auth0-spa-js | Use @auth0/auth0-nuxt |
| Auth0 app type "Single Page Application" | Use "Regular Web Application" |
Env vars: VITE_AUTH0_* or VUE_APP_AUTH0_* | Use NUXT_AUTH0_* prefix |
Using useUser() for security checks | Use useAuth0(event).getSession() server-side |
| Missing callback URLs in Auth0 Dashboard | Add http://localhost:3000/auth/callback |
| Weak/missing session secret | Generate: openssl rand -hex 64 |
Quick Setup
# 1. Install npm install @auth0/auth0-nuxt # 2. Generate secret openssl rand -hex 64
# 3. .env NUXT_AUTH0_DOMAIN=your-tenant.auth0.com NUXT_AUTH0_CLIENT_ID=your-client-id NUXT_AUTH0_CLIENT_SECRET=your-client-secret NUXT_AUTH0_SESSION_SECRET=<from-openssl> NUXT_AUTH0_APP_BASE_URL=http://localhost:3000 NUXT_AUTH0_AUDIENCE=https://your-api # optional
// 4. nuxt.config.ts export default defineNuxtConfig({ modules: ['@auth0/auth0-nuxt'], runtimeConfig: { auth0: { domain: '', clientId: '', clientSecret: '', sessionSecret: '', appBaseUrl: 'http://localhost:3000', audience: '', // optional }, }, })
Built-in Routes
The SDK automatically mounts these routes:
| Route | Method | Purpose |
|---|---|---|
/auth/login | GET | Initiates login flow. Supports ?returnTo=/path parameter |
/auth/callback | GET | Handles Auth0 callback after login |
/auth/logout | GET | Logs user out and redirects to Auth0 logout |
/auth/backchannel-logout | POST | Receives logout tokens for back-channel logout |
Customize: Pass routes: { login, callback, logout, backchannelLogout } or mountRoutes: false to module config.
Composables
| Composable | Context | Usage |
|---|---|---|
useAuth0(event) | Server-side | Access getUser(), getSession(), getAccessToken(), logout() |
useUser() | Client-side | Display user data only. Never use for security checks |
// Server example const auth0 = useAuth0(event); const session = await auth0.getSession();
<script setup> const user = useUser(); </script> <template> <div v-if="user">Welcome {{ user.name }}</div> <template>
Protecting Routes
Three layers: Route middleware (client), server middleware (SSR), API guards.
// middleware/auth.ts - Client navigation export default defineNuxtRouteMiddleware((to) => { if (!useUser().value) return navigateTo(`/auth/login?returnTo=${encodeURIComponent(to.path)}`); });
// server/middleware/auth.server.ts - SSR protection export default defineEventHandler(async (event) => { const url = getRequestURL(event); const auth0Client = useAuth0(event); const session = await auth0Client.getSession(); if (!session) { return sendRedirect(event, `/auth/login?returnTo=${encodeURIComponent(url.pathname)}`); } });
// server/api/protected.ts - API endpoint protection export default defineEventHandler(async (event) => { const auth0Client = useAuth0(event); const session = await auth0Client.getSession(); if (!session) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized' }); } return { data: 'protected data' }; });
For role-based, permission-based, and advanced patterns: route-protection.md
Session Management
Stateless (Default)
Uses encrypted, chunked cookies. No configuration needed.
Stateful (Redis, MongoDB, etc.)
For larger sessions or distributed systems:
// nuxt.config.ts modules: [ ['@auth0/auth0-nuxt', { sessionStoreFactoryPath: '~/server/utils/session-store-factory.ts' }] ]
For complete session store implementations, see: session-stores.md
API Integration
Configure audience for API access tokens:
// nuxt.config.ts runtimeConfig: { auth0: { audience: 'https://your-api-identifier', } }
Retrieve tokens server-side:
// server/api/call-api.ts export default defineEventHandler(async (event) => { const auth0Client = useAuth0(event); const { accessToken } = await auth0Client.getAccessToken(); return await $fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${accessToken}` } }); });
Security Checklist
- ✅ Server-side validation only (never trust
useUser()) - ✅ HTTPS in production
- ✅ Strong session secret (
openssl rand -hex 64) - ✅ Never commit
.envfiles - ✅ Stateful sessions for PII/large data
Troubleshooting
| Error | Solution |
|---|---|
| "Module not found" | Install @auth0/auth0-nuxt, not @auth0/auth0-vue |
| "Missing domain/clientId/clientSecret" | Check NUXT_AUTH0_ prefix, .env location, runtimeConfig |
| "Redirect URI mismatch" | Match Auth0 Dashboard callback to appBaseUrl + /auth/callback |
| "useAuth0 is not defined" | Use only in server context with H3 event object |
| Cookies too large | Use stateful sessions or reduce scopes |
Additional Resources
Guides: Route Protection Patterns • Custom Session Stores • Common Examples
Links: Auth0-Nuxt GitHub • Auth0 Docs • Nuxt Modules