Authentication with NextAuth / Auth.js & JWT Session Management0%
Metadata API: Dynamic SEO, OpenGraph Tags & Sitemap Generation

Authentication with NextAuth / Auth.js & JWT Session Management

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Authentication with NextAuth / Auth.js & JWT Session Management

Securing user identity across Server Components, Client Components, and API Route Handlers is essential for modern applications. Auth.js (formerly NextAuth.js) is the complete, open-source authentication solution for Next.js, supporting OAuth social logins (Google, GitHub), Credentials login, database adapters, and stateless JWT sessions.


1. Setting Up Auth.js in Next.js 15

Install the core package:

Bash / Terminal
npm install next-auth@beta

Create the centralized configuration file:

TypeScript
// auth.ts
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
import Google from 'next-auth/providers/google';
import Credentials from 'next-auth/providers/credentials';
import bcrypt from 'bcrypt';
import dbConnect from '@/lib/dbConnect';
import User from '@/models/User';
 
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
GitHub({
clientId: process.env.AUTH_GITHUB_ID,
clientSecret: process.env.AUTH_GITHUB_SECRET
}),
Google({
clientId: process.env.AUTH_GOOGLE_ID,
clientSecret: process.env.AUTH_GOOGLE_SECRET
}),
Credentials({
credentials: {
email: { label: 'Email', type: 'email' },
password: { label: 'Password', type: 'password' }
},
authorize: async (credentials) => {
await dbConnect();
const user = await User.findOne({ email: credentials.email }).select('+password');
if (!user) return null;
 
const isMatch = await bcrypt.compare(credentials.password as string, user.password);
if (!isMatch) return null;
 
return { id: user._id.toString(), name: user.name, email: user.email, role: user.role };
}
})
],
callbacks: {
jwt({ token, user }) {
if (user) {
token.id = user.id;
token.role = (user as any).role;
}
return token;
},
session({ session, token }) {
if (session.user) {
(session.user as any).id = token.id;
(session.user as any).role = token.role;
}
return session;
}
},
session: { strategy: 'jwt' }
});

2. Exposing Route Handlers

Wire up the authentication endpoints in the App Router:

TypeScript
// app/api/auth/[...nextauth]/route.ts
import { handlers } from '@/auth';
export const { GET, POST } = handlers;

3. Protecting Server Components & Pages

In Server Components, reading the active user session is a clean, synchronous one-liner with zero client-side waterfall:

TSX
// app/dashboard/page.tsx
import { auth } from '@/auth';
import { redirect } from 'next/navigation';
 
export default async function DashboardPage() {
const session = await auth(); // Inspect session directly on the server!
 
if (!session?.user) {
redirect('/api/auth/signin');
}
 
return (
<div className="p-8">
<h1 className="text-2xl font-bold">Welcome back, {session.user.name}!</h1>
<p>Role: {(session.user as any).role}</p>
</div>
);
}

Interactive Quiz

Multiple Choice Questions

Question 1
How do you access the active authenticated user session inside an async React Server Component using Auth.js?
Question 2
Which session strategy stores user session state securely inside an encrypted HTTP-Only cookie without requiring a database query on every request?
Question 3
Which callback in Auth.js is used to inject custom claims (such as a user's role or organization ID) into the client session object?
Question 4
What is the role of app/api/auth/[...nextauth]/route.ts?
Question 5
Why is useSession() restricted strictly to Client Components marked with 'use client'?

Next Lesson

Metadata API: Dynamic SEO, OpenGraph Tags & Sitemap Generation

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext