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

Google GitHub Facebook
📧

Email Authentication

Passwordless email magic links

Magic Links No Password Secure
🔑

Credentials

Username and password authentication

Custom Login Database Flexible
🛡️

Built-in Security

CSRF protection and secure sessions

CSRF Tokens Encrypted Safe

🔹 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>
  )
}

🧠 Test Your Knowledge

Which hook provides session data in NextAuth.js?