Bits Kingdom logo with a hexagon lattice, uppercase text in white, and a minimalistic design.

How to Handle Authentication & Protected Routes in the Next.js App Router

Chapter 7: Bring your login forms, it’s time to secure your app

by Jul 2, 2025Development

Home / Development / How to Handle Authentication & Protected Routes in the Next.js App Router

Think of the last app you built with authentication. How many hoops did you jump through — passing props, syncing state, juggling client and server logic?

With the Next.js App Router, auth finally clicks into place. Instead of bolting it on with workarounds, you can handle authentication where it belongs: on the server, integrated with React Server Components and modern layouts.

This chapter shows you how — and why — NextAuth, middleware, and cookies-based logic are now your best tools for securing full-stack apps.

Why Auth Is Different in the App Router

The app/ directory changes how and where you authenticate:

  • No getServerSideProps (RSC replaces it)
  • More focus on middleware, server sessions, and cookies()

Auth Options in Next.js 15+

MethodIdeal Use CaseTools
NextAuth.jsOAuth, email login, JWT sessionsNextAuth
Custom SessionsToken-based auth, RBACcookies(), headers()
Middleware AuthGlobal route protectionmiddleware.ts
https://www.reddit.com/r/nextjs/comments/1gf2jw2/nextjs_15_starter_kit

NextAuth.js in the App Router

Install:

npm install next-auth

Create:

app/
  api/
    auth/
      [...nextauth]/route.ts

route.ts

import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';

export const authOptions = {
  providers: [GitHubProvider({ clientId: '', clientSecret: '' })],
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

Protecting Routes

You’ll create a server-side check:

// app/dashboard/page.tsx
import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/[...nextauth]/route';

export default async function Dashboard() {
  const session = await getServerSession(authOptions);

  if (!session) return <RedirectToLogin />;

  return <h1>Welcome, {session.user.name}</h1>;
}

No getServerSideProps needed. Just await inside the component — RSC-style.

Middleware for Global Route Protection

Create:

// middleware.ts
import { NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';

export async function middleware(req) {
  const token = await getToken({ req, secret: process.env.SECRET });
  const isAuthPage = req.nextUrl.pathname.startsWith('/login');

  if (!token && !isAuthPage) {
    return NextResponse.redirect(new URL('/login', req.url));
  }

  return NextResponse.next();
}

Configure:

// next.config.js
module.exports = {
  matcher: ['/dashboard/:path*', '/admin/:path*'],
};

Cookies-Based Auth (No NextAuth)

For pure cookie-based logic:

import { cookies } from 'next/headers';

export default function DashboardPage() {
  const token = cookies().get('token')?.value;
  if (!token) return redirect('/login');
  return <h1>Secret dashboard</h1>;
}

Protecting Client Components

'use client';

import { useSession } from 'next-auth/react';

export default function ClientOnly() {
  const { data: session } = useSession();
  return <div>Welcome {session?.user?.name}</div>;
}

Final Thought

Authentication in the App Router isn’t just an upgrade — it’s a simplification. You get server-driven auth, no more prop drilling, and seamless integration with React Server Components and layouts.

If you’ve been following along, here’s what we’ve covered so far:

More chapters are coming!

About the author

<a href="https://bitskingdom.com/blog/author/thomas/" target="_self">Thomas Barreto</a>
Thomas Barreto
I am a Full Stack Developer with over 3 years of experience, specializing in frontend. I’m passionate about understanding how things work and always looking for ways to improve them. I enjoy facing new challenges, learning from every experience, and achieving results as part of a team.

Explore more topics:

Let vs. Const in JavaScript: When to Use What

Do Variable Choices Really Matter?