Next-Auth in App Router of Next.js

Next.js has recently released a stable version of App Router enriched with in-built support for layouts, templates, routing, loading, and error handling.

The current version of Next-Auth documentation is published with examples of the Page Router of Next.js. This document share approach to setting up Next.js with the Next-Auth App Router.

1111b79316f6f2c73bd79ed23f6864bd_MD5

What is covered in this document?

  1. Setup of Next.js app with app router.
  2. Install Next-Auth
  3. Configuration of Github Provider
  4. Add Handler for Next-Auth
  5. Sign in and Sign out using next-auth.
  6. Session in API Routes
  7. Use session in the Server Components
  8. Use of session in the Client Components

1. Set up the Next.js app with the App router.

Follow this document to create a basic next.js app with an app router.

4620dff5e64103a76a936681d50ee7bf_MD5

Next.js app with App router.

2. Install Next-Auth

npm install next-auth

3. Configuration of Github Provider

Create a GitHub App first, providing you a client Id and Secret. Add a file auth.js in the lib folder.

Note: Generate a secret to add as NEXTAUTH_SECRET, it must be added in the auth options.

First Generate a SECRET using OpenSSL

If you don’t have openSSL, check here How to install openSSL

openssl rand -base64 32  
  
// output  
// mQ46qpFwfE1BHuqMC+qlm19qBAD9fVPgh28werwe3ASFlAfnKjM=

next. config.js

/** @type {import('next').NextConfig} */  
const nextConfig = {  
  images: {  
    remotePatterns: [  
      {  
        protocol: 'https',  
        hostname: 'i.imgur.com',  
      },  
    ],  
  },  
  env: {  
    GITHUB_APP_CLIENT_ID: '919b87qa4sdfs1qdc44f53baf9',  
    GITHUB_APP_CLIENT_SECRET: '2aeq98df3f8cwqerc2d03a8360e993c115ba8d5f71de9',  
    NEXTAUTH_SECRET: 'mQ46qpFwfE1BHuqMC+qlm19qBAD9fVPgh28werwe3ASFlAfnKjM=',  
  },  
};  
  
module.exports = nextConfig;

4. Add Handler for Next-Auth

/lib/authOptions.js

import { NextAuthOptions } from 'next-auth';  
import GithubProvider from 'next-auth/providers/github';  
export const authOptions: NextAuthOptions = {  
  // Secret for Next-auth, without this JWT encryption/decryption won't work  
  secret: process.env.NEXTAUTH_SECRET,  
    
  // Configure one or more authentication providers  
  providers: [  
    GithubProvider({  
      clientId: process.env.GITHUB_APP_CLIENT_ID as string,  
      clientSecret: process.env.GITHUB_APP_CLIENT_SECRET as string,  
    }),  
  ],  
};

Next-Auth Handler

Create a file route.js in the folder /app/auth/[…nextauth]

852f40f81c3f835b85b2d32954ece801_MD5
import NextAuth from 'next-auth';  
import { authOptions } from '@/app/lib/authOptions';  
  
const handler = NextAuth(authOptions);  
export { handler as GET, handler as POST };

Configuration is completed here, Now setup Signin and Signout button.

5. Sign in and Sign out using next-auth

Signin by /api/auth/*

All requests to any of these paths/api/auth/* (signIncallbacksignOut, etc.) will be handled by NextAuth.js.

Once you click the button, log in, and authorize the app, it will get a cookie in the session.

89f9e40364a8e27ea3b95574874e931d_MD5

Next-Auth default Sign in page

After successful sign-in.

47dd9b49c1a3131df9a32703b041415e_MD5

Next-Auth token

How to create Signin button for specific Provider.

// Note buttons will only work if you have added configuration in the authOptions  
  
import { signIn } from 'next-auth/react';  
  
//Facebook Button  
  
<button onClick={() => signIn('facebook')}>  
    <FaFacebook className="mr-2" /> Login with Facebook  
</button>  
  
//Github Button  
  
<button onClick={() => signIn('github')}>  
    <FaFacebook className="mr-2" /> Login with Facebook  
</button>  
  
//Google Button  
<button onClick={() => signIn('google')}>  
    <FaFacebook className="mr-2" /> Login with Facebook  
</button>

Sign Out

use this link /api/auth/signout to sign out.

OR

use signout() method by nextauth, this is recommended way due to any future changes in the API’s.


import { signOut} from 'next-auth/react';  
 
<button onClick={() => signOut()}> Signout </button>

6. Session in API routes.

API route handlers are considered server components. It can be a static or dynamic handler but these are always on the server side.

import { authOptions } from '@/app/lib/auth';  
import { getServerSession } from 'next-auth';  
import { NextResponse } from 'next/server';  
  
export async function GET(request: Request) {  
  const session = await getServerSession(authOptions);  
  console.log(session);  
  return NextResponse.json({   
	  id: 1,  
  });
}

Output

{  
  user: {  
    name: 'Rohit Kumar Khatri',
    email: 'er.rohitkumar@outlook.com',
    image: 'https://avatars.githubusercontent.com/u/34018015?v=4 }
}

7. Session in Server Components

It is also similar in all server components. Use the same function as mentioned above.

import { getServerSession } from 'next-auth';

await getServerSessionauthOptions);

8. Session in Client Components

First, add Session Provider in the Root Layout

'use client';  
  
import { SessionProvider } from 'next-auth/react';  
import { ReactNode } from 'react';  
  
export default function NextAuthProvider({  
  children,  
}: {  
  children: ReactNode;  
) {  return <SessionProvider>{children}</SessionProvider>;
}
import { useSelectedLayoutSegments } from 'next/navigation';  
import './globals.css';  
import { Inter } from 'next/font/google';  
import Footer from '@/app/components/Footer';  
import Navbar from '@/app/components/Navbar';  
import NextAuthProvider from '@/app/context/NextAuthProvider';  
import { ReactNode } from 'react';  
const inter = Inter({ subsets: ['latin'] });  
  
export default function RootLayout({ children }: { children: ReactNode }) {  
  return (  
    <html lang="en">  
      <body className={`inter.className`}>  
        <NextAuthProvider>  
          <div className="w-10/12 m-auto text-center bg-white flex flex-col min-h-screen">  
            <div>  
              <Navbar />  
            </div>  
            <div className="grow">{children}</div>  
            <Footer />  
          </div>  
        </NextAuthProvider>  
      </body>  
    </html>  
  );  
}

Now use session in any client component.

'use client';  
  
import { useSession } from 'next-auth/react';  
  
export default function ClientComponent() {  const { data: session, status } = useSession();  return (  
    <div>  
      ClientComponent {status}{' '}  
      {status = 'authenticated' && session.user?.name}  
    </div>  
  );  
}
Clap here if you liked the blog