Next js

Module 9: Authentication & Authorization in Next.js 14 with TypeScript

Add Login, Protect Pages, and Implement Role-Based Access using NextAuth.js

Secure user authentication is essential for any real-world web app. In this module, you’ll learn how to:

  • Set up NextAuth.js with Google/GitHub login
  • Customize the sign-in UI
  • Protect routes with middleware
  • Add role-based UI (admin vs. user)

✅ Step 1: Install and Configure next-auth

npm install next-auth

🔹 Add API Route: src/app/api/auth/[...nextauth]/route.ts

// src/app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";

const handler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async session({ session, token }) {
      session.user.id = token.sub; // Add user ID
      session.user.role = token.email === 'admin@example.com' ? 'admin' : 'user'; // Basic role logic
      return session;
    },
  },
});

export { handler as GET, handler as POST };

🔹 Add Environment Variables

In your .env.local:

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
NEXTAUTH_SECRET=some-long-random-string
NEXTAUTH_URL=http://localhost:3000

Use https://generate-secret.vercel.app/32 to generate your NEXTAUTH_SECRET.


✅ Step 2: Setup Auth Provider

Wrap your app with SessionProvider.

🔹 src/app/layout.tsx

import { SessionProvider } from "next-auth/react";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <SessionProvider>{children}</SessionProvider>
      </body>
    </html>
  );
}

✅ Step 3: Add Login / Logout Buttons

🔹 src/components/AuthButton.tsx

"use client";

import { signIn, signOut, useSession } from "next-auth/react";

export default function AuthButton() {
  const { data: session } = useSession();

  if (session?.user) {
    return (
      <div className="flex items-center gap-4">
        <span>Welcome, {session.user.name}</span>
        <button onClick={() => signOut()} className="text-red-600">Logout</button>
      </div>
    );
  }

  return <button onClick={() => signIn("google")} className="text-blue-600">Login with Google</button>;
}

✅ Step 4: Protect Routes with Middleware

🔹 middleware.ts

import { getToken } from "next-auth/jwt";
import { NextResponse } from "next/server";

export async function middleware(req: Request) {
  const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });

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

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"], // Protect dashboard routes
};

✅ Step 5: Add Custom Login Page (Optional)

Create src/app/login/page.tsx:

"use client";
import { signIn } from "next-auth/react";

export default function LoginPage() {
  return (
    <div className="p-8 text-center">
      <h1 className="text-2xl font-bold mb-4">Login Required</h1>
      <button
        onClick={() => signIn("google")}
        className="bg-blue-600 text-white px-4 py-2 rounded"
      >
        Sign in with Google
      </button>
    </div>
  );
}

✅ Step 6: Role-Based UI Rendering

In any page or component:

"use client";
import { useSession } from "next-auth/react";

export default function Dashboard() {
  const { data: session } = useSession();

  if (!session) return <p>Loading...</p>;

  return (
    <div className="p-6">
      <h1 className="text-xl">Dashboard</h1>
      {session.user.role === "admin" ? (
        <p className="text-green-600">Admin Access</p>
      ) : (
        <p>User Access</p>
      )}
    </div>
  );
}

✅ Roles are customizable in the session callback!


✅ Summary

Feature Tool / Example
Auth integration next-auth
OAuth login Google/GitHub providers
Protect pages middleware.ts + matcher
Session access useSession() from next-auth/react
Custom roles Add role via session() callback

🔜 Coming Up Next:

In Module 10, we’ll learn how to optimize performance, handle SEO, add environment variables, and deploy your app to Vercel with custom domains and CI/CD setup.

Would you like Module 9 converted to Markdown or HTML for your blog?

Leave a Reply

Your email address will not be published. Required fields are marked *