NextAuth.js Authentication
Add secure authentication to your Next.js app
🔐 What is NextAuth.js?
NextAuth.js is a complete authentication solution for Next.js applications. It supports multiple providers like Google, GitHub, and email, with built-in security features and session management for easy implementation.
import { signIn, signOut, useSession } from 'next-auth/react'
export default function Component() {
const { data: session } = useSession()
return session ? <button onClick={() => signOut()}>Sign out</button> : <button onClick={() => signIn()}>Sign in</button>
}
Key Authentication Features
OAuth Providers
Support for popular OAuth providers
Email Authentication
Passwordless email magic links
Credentials
Username and password authentication
Built-in Security
CSRF protection and secure sessions
🔹 Basic Setup
Install NextAuth.js and create the authentication API route. This sets up the foundation for all authentication providers and handles sign-in, sign-out, and session management automatically.
# Install NextAuth.js
npm install next-auth
🔸 Create Auth Route
// app/api/auth/[...nextauth]/route.js
import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
}
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
Result:
✅ Authentication API ready
✅ Google sign-in enabled
✅ Session management active
🔹 Session Provider
Wrap your app with SessionProvider to make session data available throughout your application. This enables useSession hook and automatic session updates across all components.
// app/layout.js
import { SessionProvider } from 'next-auth/react'
export default function RootLayout({ children }) {
return (
<html>
<body>
<SessionProvider>
{children}
</SessionProvider>
</body>
</html>
)
}
SessionProvider benefits:
- Access session in any component
- Automatic session refresh
- Real-time authentication state
- Optimized re-renders
🔹 Sign In Component
Create a sign-in button that triggers authentication. The useSession hook provides current session state and the signIn function handles the authentication flow with your configured providers.
'use client'
import { useSession, signIn, signOut } from 'next-auth/react'
export default function LoginButton() {
const { data: session } = useSession()
if (session) {
return (
<div>
<p>Welcome, {session.user.name}!</p>
<button onClick={() => signOut()}>
Sign Out
</button>
</div>
)
}
return (
<button onClick={() => signIn('google')}>
Sign in with Google
</button>
)
}
Result:
✅ Shows sign-in button when logged out
✅ Shows user info when logged in
✅ Handles sign-out functionality
🔹 Protected Routes
Protect pages by checking authentication status. Redirect unauthenticated users to login page while allowing authenticated users to access protected content securely.
🔸 Client-Side Protection
'use client'
import { useSession } from 'next-auth/react'
import { redirect } from 'next/navigation'
export default function ProtectedPage() {
const { data: session, status } = useSession()
if (status === 'loading') {
return <p>Loading...</p>
}
if (!session) {
redirect('/api/auth/signin')
}
return (
<div>
<h1>Protected Content</h1>
<p>Only logged in users see this!</p>
</div>
)
}
🔸 Server-Side Protection
import { getServerSession } from 'next-auth'
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
import { redirect } from 'next/navigation'
export default async function AdminPage() {
const session = await getServerSession(authOptions)
if (!session) {
redirect('/api/auth/signin')
}
return <h1>Admin Dashboard</h1>
}
🔹 Multiple Providers
Add multiple authentication providers to give users options. Each provider requires its own credentials from the respective service's developer console.
// app/api/auth/[...nextauth]/route.js
import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import GitHubProvider from 'next-auth/providers/github'
import EmailProvider from 'next-auth/providers/email'
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
}),
],
}
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
🔹 Custom Sign-In Page
Create a custom sign-in page with your own design and branding. This gives you full control over the authentication user interface and experience.
// app/api/auth/[...nextauth]/route.js
export const authOptions = {
pages: {
signIn: '/auth/signin',
},
// ... other options
}
// app/auth/signin/page.js
'use client'
import { signIn } from 'next-auth/react'
export default function SignIn() {
return (
<div>
<h1>Sign In</h1>
<button onClick={() => signIn('google')}>
Google
</button>
<button onClick={() => signIn('github')}>
GitHub
</button>
</div>
)
}