Matthew Powell
Matthew Powell

Reputation: 91

getServerSession() returning null in api route when using NextJs and Next-Auth

I'm new to NextJS and Next-Auth. I'm trying to write a secure api route that is only available if a user is logged in. I sucessfully accessing the session on the client side using useSession() but when I try to implement the logic in an api route the session always returns null. I have tried to copy the simpliest example from the docs. Am I missing something?

Here is my route in src/pages/api/users/getUser.ts:

import { getServerSession } from 'next-auth/next'
import { authOptions } from '../auth/[...nextauth]'
import { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const session = await getServerSession(req, res, authOptions)
  console.log('session', session)

  if (session) {
    res.send({ content: 'SUCCESS' })
  } else {
    res.send({ error: 'ERROR' })
  }
}

Here is my authOptions in src/pages/api/auth/[...nextauth].ts

import NextAuth from 'next-auth'
import GithubProvider from 'next-auth/providers/github'
import { PrismaAdapter } from '@next-auth/prisma-adapter'
import prisma from '../../../../prisma/db/prismadb'

export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID || '',
      clientSecret: process.env.GITHUB_SECRET || '',
    }),
  ],
  pages: {
    signIn: '/',
    signOut: '/',
  },
}

export default NextAuth(authOptions)

Here are my dependencies:

 "dependencies": {
    "@next-auth/prisma-adapter": "^1.0.5",
    "@next/font": "13.1.6",
    "@prisma/client": "^4.10.1",
    "@types/node": "18.11.19",
    "@types/react": "18.0.27",
    "@types/react-dom": "18.0.10",
    "axios": "^1.3.2",
    "dotenv-cli": "^7.0.0",
    "eslint": "8.33.0",
    "eslint-config-next": "13.1.6",
    "next": "13.1.6",
    "next-auth": "^4.19.2",
    "prisma": "^4.9.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "styled-components": "^5.3.6",
    "typescript": "4.9.5"
  },
  "devDependencies": {
    "@types/styled-components": "^5.1.26"
  }

Upvotes: 9

Views: 7538

Answers (5)

CrackerKSR
CrackerKSR

Reputation: 1916

For debugging purpose remove pages first

  pages: {
    signIn: '/',
    signOut: '/',
  },
``

Create a button which triggers signin method.

Access session like this

const session = getServerSession(authOptions) console.log({session})



I do not know about pages beacuse I could not configure it for my use so I have been using the default sign in page provided by next-auth.

But what I have mention works fine and returns session in clients and server both.

If above solution works then try sending requests. No need to pass headers or authorization.

Upvotes: 0

David Ajibola
David Ajibola

Reputation: 1

Trying adding the NEXTAUTH_SECRET environment variable and using it in your authOptions. It worked for me.

https://next-auth.js.org/deployment

Upvotes: 0

Prajil K
Prajil K

Reputation: 92

Using headers: headers() might give you some error when deploying to vercel. I got this error ReadonlyHeadersError: Headers cannot be modified..

I solved the problem by sending Cookie with the request like this,

import { headers } from "next/headers"

const headersList = headers();
const cookie = headersList.get('cookie');

const response = await fetch("api/posts", {
  method: "GET",
  headers: {
    'Cookie': cookie
  }
})

Upvotes: 4

S J
S J

Reputation: 530

If you're calling the API route from a server component, the cookies are not passed via fetch by default, so you have to send the headers through your API call.

So you can do this:

import { headers } from "next/headers"

const response = await fetch("api/posts", {
  method: "GET",
  headers: headers()
})

Note that if you're in a server component, you don't have to call the API, you can do the stuff directly like fetching data from database or other things.

Upvotes: 13

user21242515
user21242515

Reputation: 11

In my case, when NEXTAUTH_URL is 127.0.0.1 and API is requested to localhost, the session is null.

So, I solved the problem by matching the NEXTAUTH_URL with the request URL.

Upvotes: 1

Related Questions