NextAuth Get Session in App Router API Route – Typescript

by
Liam Thompson
app-router next-auth next.js next.js13 react-typescript

Quick Fix: To retrieve the session in an API route, simply invoke getServerSession() with the authOptions object, omitting the req and res parameters. This will return the session object, which you can then utilize within your API route.

The Problem:

While using NextAuth and Next.js’s App Router, you’ve created an API route in the /app/api folder, but you can’t get the session associated with the API request. You tried using getServerSession(req) inside the API route handler, but that results in an error: Invalid Compact JWE. Your aim is to retrieve the session corresponding to the HTTP request using Next.js’s App Router.

The Solutions:

Solution 1: Pass `authOptions` to `getServerSession`

To retrieve the session corresponding to the HTTP request with Next’s new API routes, you can simply pass authOptions to getServerSession without the req and res parameters. Here’s an example:

export async function GET(req: NextApiRequest) {
  const session = await getServerSession(authOptions);

  console.log(session);

  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

This should resolve the error TypeError: res.getHeader is not a function and allow you to access the session object in your API route.

The authOptions parameter is an object that contains the necessary configuration options for your NextAuth setup, such as the secret, adapter, and callback URL. You can find more information about authOptions in the NextAuth documentation.

Solution 2: Pass jwt related information to `getServerSession`

  1. First, you need to define authOptions which is an object that contains JWT related information, such as your secret, signing key, and JWT callback.

  2. Then, pass req, res, and authOptions to getServerSession.

Here’s an example:

export async function GET(req: NextApiRequest, res: NextApiResponse) {
  const authOptions = {
    secret: process.env.JWT_SECRET,
    signingKey: process.env.JWT_SIGNING_KEY,
    jwt: {
      // if you are using MongoDB adapter - you need to pass signing key to it            
      signingKey: process.env.JWT_SIGNING_KEY,
      verificationOptions: {
        // if you are using MongoDB adapter - you need to pass signing key to it            
        algorithms: ['HS256'],
      },
    },
  };

  const session = await getServerSession(req, res, authOptions);

  console.log(session);

  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

This should allow you to retrieve the session corresponding to the HTTP request.

Solution 3: Set `authOptions.secret` or `authOptions.session` Manually

If you are using a custom auth adapter, you need to pass the authOptions.secret or authOptions.session manually.

<!– begin snippet: js hide: false console: true babel: false –>

<!– language: lang-js –>

const session = await getServerSession(req, res, {
  secret: process.env.SECRET,
  session: {
    jwt: true,
  },
});

<!– end snippet –>

Q&A

I don’t have access to res and req object to pass in the normal getServerSession(req, res, authOptions) method, How can I get the session?

Pass only authOptions to getServerSession(authOptions).

It seems like I’m missing out on passing necessary information to getServerSession. What needs to be included?

Ensure authOptions is passed to getServerSession.

Can I access Cookies in server side as well as cleint side?

Yes, In server side you need to pass cookie in request header whereas in client side it’s already available.

Video Explanation:

The following video, titled "Next-Auth on App Router - Solid Auth, Super Fast - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

... React Server Components 10:53 Protected Routes 12:31 Auth In Server Actions 14:19 Auth In API Routes 15:33 Proxied Auth In RSCs 16:38 Outro.