13

I am using nextAuth for authentication in my project and I would like to restrict certain pages for the clients that are not logged in.

I tried calling the useSession() hook in the getServerSideProps() function but I got an error for calling the hook there.

Is it possible to do a redirect on the server side using nextAuth?

Szymon Jednac
  • 2,969
  • 1
  • 29
  • 43
Benni
  • 554
  • 2
  • 8
  • 19

5 Answers5

29

You can't use the useSession hook in getServerSideProps. You need to use getSession. You can read more here. You can redirect in getServerSideProps if the session doesn't exist. Here's an example:

export async function getServerSideProps(context) {
  const session = await getSession(context)

  if (!session) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: { session }
  }
}
Santeri Sarle
  • 863
  • 7
  • 12
4

Feb 2023: With the new app/ directory feature coming with NextJS13, the auth middleware from NextAuth isn't working (at least for me).

I figured out a way to protect frontend sites easily and fast. But be aware that it is bad practice to protect only your frontend pages! Your API should be secured too!

Here's the code:

import { getServerSession } from "next-auth/next"
import { authOptions } from "pages/api/auth/[...nextauth]"
import { redirect } from 'next/navigation';

export default async function Page() {
  const session = await getServerSession(authOptions)
  if(session == null){
    return redirect("api/auth/signin")
  } else {
    return (
      <>
      <h1 className=" text-2xl">Very secure Page</h1>  
      <pre>{JSON.stringify(session, null, 2)}</pre>
      </>
    )
  }
}
Nick
  • 66
  • 2
2

NextAuth can handle redirection to a sign-in page if the user is not logged in. Take a look at the documentation

Here are the steps

  1. Create a file called middleware.ts on the same directory level as your pages folder or your app folder if you are using next js 13
  2. You can export a config object inside middleware.ts that has a matcher property assigned to an array of the routes you want to protect. In the example below I am protecting all routes that start with /admin. But you can add as many as you want since it is an array.

middleware.ts

 export { default } from "next-auth/middleware";

 export const config = {
  matcher: ["/admin/:path*"],
};
Hamza Kyamanywa
  • 417
  • 3
  • 8
0

Recommended to use middleware approach now: https://next-auth.js.org/tutorials/securing-pages-and-api-routes#server-side

Pencilcheck
  • 2,664
  • 3
  • 25
  • 14
0

Aug 2023 Update: The method getSession() has been replaced by getServerSession(). Here is an example of how to protect Server-side rendered pages:

import { getServerSession } from "next-auth/next"
import { authOptions } from "./api/auth/[...nextauth]"
import { useSession } from "next-auth/react"

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

  if (typeof window === "undefined") return null

  if (session) {
    return (
      <>
        <h1>Protected Page</h1>
        <p>You can view this page because you are signed in.</p>
      </>
    )
  }
  return <p>Access Denied</p>
}

export async function getServerSideProps(context) {
  return {
    props: {
      session: await getServerSession(
        context.req,
        context.res,
        authOptions
      ),
    },
  }
}

You can find more info here.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83