Next.js Discord

Discord Forum

How to fully implement NextAuth in Next.js with App Router?

Unanswered
Marvel posted this in #help-forum
Open in Discord
I've followed the instructions at https://next-auth.js.org, mostly on the 'Getting Started' and 'Configuration' pages. Most of the sections are for Pages Router but they also have a section for App Router at https://next-auth.js.org/configuration/initialization. But so far I haven't finished implementing all the related features.

10 Replies

Features I implemented:
- Added <SessionProvider> to src/app/layout.tsx:
// import section

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: '"TeamFlow" Internal Tools',
  description: "", // TODO: fill this in
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html className="h-full bg-gray-100 dark:bg-gray-800" lang="en">
      <body className="h-full">
        <NavBar logo={logo} user={user} userNavigations={userNavigations} />

        <div className="flex pt-16 overflow-hidden bg-gray-50 dark:bg-gray-900">
          <Sidebar navigations={navigations} />
          <div className="relative w-full h-full overflow-y-auto bg-gray-50 lg:ml-64 dark:bg-gray-900">
            <SessionProvider>
              <main>{children}</main>
            </SessionProvider>
          </div>
        </div>
      </body>
    </html>
  );
}

- Added 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!,
    }),
  ],
});

export { handler as GET, handler as POST };

- Visiting /api/auth/signin will show the Sign in with Google button
- Added Sign out button in src/app/nav-bar.tsx. This component will display a profile image icon at the top right side and when clicked will display a disclosure of where the button is located. I used import { signOut } from "next-auth/react"; serves as argument to onClicked
Here is the current project structure (/src/app):
.
└── app
    ├── api
    │   └── auth
    │       └── [...nextauth]
    │           └── route.ts
    ├── change-logs
    │   ├── [changeLogId]
    │   │   └── page.tsx
    │   ├── layout.tsx
    │   └── page.tsx
    ├── components
    │   ├── delete-comment-button.tsx
    │   ├── editable-text.tsx
    │   ├── step-list-item.tsx
    │   └── submit-button.tsx
    ├── dummies
    │   ├── logo.tsx
    │   ├── navigations.tsx
    │   ├── user-navigations.tsx
    │   └── user.tsx
    ├── favicon.ico
    ├── globals.css
    ├── interfaces
    │   └── button-props.ts
    ├── layout.tsx
    ├── nav-bar.interface.ts
    ├── nav-bar.tsx
    ├── nav-logo.interface.ts
    ├── nav-logo.tsx
    ├── page.tsx
    ├── releases
    │   ├── [releaseId]
    │   │   └── page.tsx
    │   ├── layout.tsx
    │   └── page.tsx
    ├── sidebar-item.interface.ts
    ├── sidebar-item.tsx
    ├── sidebar.interface.ts
    └── sidebar.tsx

Now I want to implement:
- Session check, by default the website will redirect to /api/auth/signin on logout which displays a Sign in with Google button. How to implement it? Can this be implemented in one place instead of checking the session using useSession on each component?
- Protecting TSX routes and components. For routes, I read it would involve using getServerSideProps but I'm not sure how and where to implement it. Same thing for TSX components
so is there an issue or a question you have with it? im kinda just not sure what you need help with
A. How to implement session checking? Can this be implemented in one place instead of checking sessions using useSession on each component? By default, websites should redirect to /api/auth/signin on logout which displays the Sign in with Google button
B. How to protect TSX routes and components? For routes, I read it would involve using getServerSideProps but I'm not sure how and where to implement it. Same thing for TSX components
you just do the checks in middleware or inside the page function (as server by default)
In src/app/page.tsx I added:
// TODO: ?

import { useSession } from "next-auth/react";
import { redirect } from "next/navigation";

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

  if (session) {
    return (
      <>
        <div className="px-4 pt-6">
          <div className="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800 xl:mb-0">
            Home
          </div>
        </div>
      </>
    );
  }
  return redirect("/api/auth/signin");
}

but even after Signing in with my Google account, the app will always redirect to /api/auth/signin.
// middleware.ts
export { default } from "next-auth/middleware"

So I just need to add this to src/app/middleware.ts?