Next.js Authentication Tutorial: Complete Guide 2026

Next.js Authentication Tutorial: Complete Guide 2026

By Elena Rodriguez · January 10, 2026 · 15 min read

Key Insight

NextAuth.js (now Auth.js) is the standard authentication solution for Next.js applications. It supports OAuth providers like Google and GitHub, email/password login, magic links, and custom credentials. This tutorial covers setup, configuration, protected routes, and API route protection.

Introduction

Authentication is essential for any application with user accounts. Next.js combined with NextAuth.js provides a robust, secure, and flexible authentication solution that works with the App Router, Server Components, and API routes.

This tutorial covers implementing authentication from scratch, including OAuth providers, credentials-based login, and protecting routes.

Prerequisites

  • Next.js 14+ application
  • Basic React and Next.js knowledge
  • Node.js 18+

Installation

Install NextAuth.js (now called Auth.js) using npm or yarn. You will also need any database adapters if using database sessions.

Create the necessary environment variables for your secret key and OAuth provider credentials.

Basic Setup

Create Auth Configuration

Create an auth configuration file that defines your providers and callbacks. This is where you configure how authentication works in your application.

Set Up API Route

Create the NextAuth API route handler. This handles all authentication endpoints like sign in, sign out, and callbacks.

Add Session Provider

Wrap your application with the SessionProvider to make authentication state available throughout your app.

OAuth Providers

Google Sign-In

Google OAuth is one of the most popular authentication methods. Configure it by:

  1. Create a project in Google Cloud Console
  2. Enable the OAuth 2.0 API
  3. Create OAuth credentials
  4. Add authorized redirect URIs
  5. Add client ID and secret to environment variables

GitHub Sign-In

GitHub OAuth is popular for developer-focused applications:

  1. Create an OAuth App in GitHub Developer Settings
  2. Set the authorization callback URL
  3. Add client ID and secret to environment variables

Credentials Provider

For email/password authentication, use the Credentials provider. This requires:

  1. A user database
  2. Password hashing (use bcrypt)
  3. Custom authorize function

The authorize function receives credentials and should:

  • Look up the user by email
  • Verify the password hash
  • Return the user object or null

Important: Handle errors securely without revealing whether the email exists.

Protecting Routes

Client-Side Protection

Use the useSession hook to check authentication status and redirect unauthorized users.

Server-Side Protection

For Server Components, use getServerSession to check authentication. This is more secure as it runs on the server.

Middleware Protection

Create a middleware.ts file to protect entire route groups. This runs before requests reach your pages.

Configure which routes require authentication using the matcher pattern.

Customizing Pages

Custom Sign-In Page

Create a custom sign-in page for better UX. Configure NextAuth to use your custom page instead of the default.

Your custom page should include forms for each provider and handle errors appropriately.

Custom Error Page

Handle authentication errors gracefully with a custom error page that explains what went wrong.

Session Management

Accessing Session Data

On the client, use the useSession hook. It returns session data, loading status, and update function.

On the server, use getServerSession. This is secure and can be used in Server Components and API routes.

Extending Session Data

Add custom fields to the session by extending the callbacks. For example, add user role or ID.

Database Adapters

For persistent sessions and user storage, use a database adapter.

Popular options:

  • Prisma: Works with many databases
  • Drizzle: Lightweight, TypeScript-first
  • MongoDB: For document-based storage

The adapter handles user creation, session storage, and account linking.

Security Best Practices

Environment Variables

Never commit secrets to version control. Use environment variables for:

  • NEXTAUTH_SECRET (generate with openssl rand -base64 32)
  • OAuth client IDs and secrets
  • Database connection strings

CSRF Protection

NextAuth includes CSRF protection by default. Do not disable it.

Secure Cookies

In production, cookies are automatically set to secure and httpOnly. Verify your deployment uses HTTPS.

Rate Limiting

Add rate limiting to authentication endpoints to prevent brute force attacks.

Testing

Development Testing

Use test accounts for OAuth providers during development. Most providers have sandbox modes.

E2E Testing

For end-to-end tests, mock the session provider or use test credentials. Playwright and Cypress both support this.

Deployment

Ensure your production environment has:

  • NEXTAUTH_URL set to your production URL
  • NEXTAUTH_SECRET as a strong random string
  • OAuth callback URLs updated for production
  • Database connection string for production database

Conclusion

NextAuth.js provides a comprehensive authentication solution for Next.js applications. Start with OAuth providers for quick implementation, add credentials if needed, and protect your routes appropriately.

Focus on security from the start—use environment variables, enable CSRF protection, and implement rate limiting. The library handles most security concerns, but understanding the underlying mechanisms helps you make better decisions.

Key Takeaways

  • NextAuth.js handles OAuth, credentials, and magic links
  • Configure providers in your auth options file
  • Use useSession hook for client-side auth state
  • Protect routes with middleware or getServerSession
  • Store sessions in JWT or database depending on needs
  • Customize sign-in pages for better UX

Frequently Asked Questions

Is NextAuth.js free to use?

Yes, NextAuth.js is completely free and open source. The only costs are for any external services you use, like databases for session storage or email providers for magic links. OAuth providers like Google and GitHub are also free for authentication.

Should I use JWT or database sessions?

JWT sessions are stateless and work well for simple applications without a database. Database sessions are better when you need to revoke sessions, track active sessions, or store additional user data. For most applications, JWT is simpler to start with.

How do I protect API routes in Next.js?

Use getServerSession in API routes to check authentication. If no session exists, return a 401 status. For middleware-based protection, use the middleware.ts file to check authentication before requests reach your routes.