Authentification Next.js (Auth.js v5)
Règles
- Centraliser la configuration dans
auth.ts (export NextAuth() : handlers, auth, signIn, signOut). Ne jamais disperser les secrets des fournisseurs.
- Protéger les routes dans
middleware.ts (wrapper auth compatible Edge) et revérifier la session dans les Server Actions/mutations — le middleware est pour l'expérience utilisateur, pas pour l'autorisation.
- Lire la session dans les Server Components via
await auth(). Dans les Client Components, utiliser useSession() de next-auth/react avec <SessionProvider>.
- Ne jamais exposer les secrets (
AUTH_SECRET, clés des fournisseurs) avec le préfixe NEXT_PUBLIC_. Valider les variables d'environnement avec Zod au démarrage.
- Vérifications de rôles : étendre le type de session via l'augmentation de module (
user.role), appliquer côté serveur.
Patterns
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [GitHub],
callbacks: {
async session({ session, token }) {
if (session.user) (session.user as { role?: string }).role = token.role as string;
return session;
},
async jwt({ token, user }) {
if (user) token.role = (user as { role?: string }).role ?? 'user';
return token;
},
},
});
export { auth as middleware } from '@/auth';
export const config = { matcher: ['/dashboard/:path*', '/admin/:path*'] };
import { handlers } from '@/auth';
export const { GET, POST } = handlers;
import { auth } from '@/auth';
import { redirect } from 'next/navigation';
export default async function AdminPage() {
const session = await auth();
if (!session?.user) redirect('/login');
if ((session.user as { role?: string }).role !== 'admin')
redirect('/dashboard');
return <AdminView />;
}
import 'next-auth';
declare module 'next-auth' {
interface User { role?: string }
}
Liste de vérification