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.
What is covered in this document?
- Setup of Next.js app with app router.
- Install Next-Auth
- Configuration of Github Provider
- Add Handler for Next-Auth
- Sign in and Sign out using next-auth.
- Session in API Routes
- Use session in the Server Components
- 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.
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]
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/*
(signIn
, callback
, signOut
, 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.
Next-Auth default Sign in page
After successful sign-in.
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>
);
}