To secure Auth0 + Next.js integration, you need to: (1) use @auth0/nextjs-auth0 SDK for secure session management, (2) protect API routes with withApiAuthRequired wrapper, (3) check getSession() in Server Components before rendering protected content, (4) configure proper audience for API access tokens, and (5) use a strong AUTH0_SECRET (32+ characters). This blueprint ensures authentication flows follow security best practices.
TL;DR
Use @auth0/nextjs-auth0 for secure session management. It handles token refresh and storage automatically, so you're not rolling that logic yourself. Protect API routes with withApiAuthRequired, and check Server Components with getSession before rendering anything protected. Set the right audience if you're issuing API access tokens.
Auth0 Configuration Auth0
# Auth0 Configuration
AUTH0_SECRET='long-random-string-at-least-32-chars'
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://your-tenant.auth0.com'
AUTH0_CLIENT_ID='your-client-id'
AUTH0_CLIENT_SECRET='your-client-secret'
# For API access tokens (optional)
AUTH0_AUDIENCE='https://your-api.example.com'
API Route Handler Setup
import { handleAuth, handleLogin } from '@auth0/nextjs-auth0'
export const GET = handleAuth({
login: handleLogin({
authorizationParams: {
audience: process.env.AUTH0_AUDIENCE,
scope: 'openid profile email',
},
}),
})
Protected API Route Next.js
import { withApiAuthRequired, getSession } from '@auth0/nextjs-auth0'
import { NextResponse } from 'next/server'
export const GET = withApiAuthRequired(async (req) => {
const session = await getSession()
if (!session?.user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Use session.user.sub as the unique user ID
const posts = await db.posts.findMany({
where: { authorId: session.user.sub },
})
return NextResponse.json(posts)
})
Protected Server Component
import { getSession } from '@auth0/nextjs-auth0'
import { redirect } from 'next/navigation'
export default async function Dashboard() {
const session = await getSession()
if (!session?.user) {
redirect('/api/auth/login')
}
return (
<div>
<h1>Welcome, {session.user.name}</h1>
<p>User ID: {session.user.sub}</p>
</div>
)
}
Always call getSession() server-side. The session lives in an encrypted cookie the SDK manages for you. Don't expose raw tokens to the client unless an API call genuinely needs them.
Security Checklist
Pre-Launch Checklist
AUTH0_SECRET is strong (32+ chars)
API routes use withApiAuthRequired
Server Components check getSession()
Callback URLs configured in Auth0
Audience set for API access tokens
Related Integration Stacks
Clerk + Next.js Alternative NextAuth + Prisma Self-Hosted OAuth Security Patterns
Check Your Auth0 Integration
Scan for authentication security issues.