0

I am trying to figure out what could be the reason why I am able to successfully make a client-side call for the session and server-side call in a server component page, but when I make the call with an API route, it is returning undefined.

Here is a working server component with a server-side call (/app/profile):

import FeedCard from '@/components/application/feed/FeedCard';
import { authOptions } from '@/pages/api/auth/[...nextauth]';
import { getServerSession } from 'next-auth';

export default async function Feed() {
  const session = await getServerSession(authOptions);

  return (
    <div className="container mx-auto">
      <div className="flex flex-col">
        <div className="my-5">
          <h1 className="text-5xl font-black mb-5">Feed</h1>
          <p>
            <strong>Welcome, </strong>
            {session?.user?.name}!
          </p>
          <pre>{JSON.stringify(session)}</pre>
        </div>
        <FeedCard />
      </div>
    </div>
  );
}

Here is a working client component call (/app/navigation):

'use client'

import React, { useState } from 'react';
import Link from 'next/link';
import { useSession, signOut } from 'next-auth/react';

const AppMainNavigation = () => {
  const { data: session, status } = useSession();
  console.log(session)
  return (
    <div>Test</div>
  )
}

Here is the API call that is returning undefined for getServerSession():

import prisma from '@/libs/client';
import { getServerSession } from 'next-auth/next';
import { authOptions } from './auth/[...nextauth]';

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const session = await getServerSession(req, res, authOptions);
    console.log(`===== session ======`);
    console.log(`session: ${session}`);

  }
}

Server console.log:

===== session ======
session: null

Here is the [...nextauth].ts:

import NextAuth from 'next-auth';
import type { NextAuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import prisma from '@/libs/client';
const bcrypt = require('bcrypt');

const confirmPasswordHash = (plainPassword, hashedPassword) => {
  return new Promise((resolve) => {
    bcrypt.compare(plainPassword, hashedPassword, function (err, res) {
      resolve(res);
    });
  });
};

export const authOptions: NextAuthOptions = {
  // Configure one or more authentication providers
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: 'email', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      // Authorization
      async authorize(credentials) {
        const { email, password } = credentials;
        const formPassword = credentials.formPassword;
        const authFormType = credentials.newUser ? formPassword : password;

        try {
          if (!email || !password) {
            console.log('No Email or Password Provided');
            return null;
          }

          const user = await prisma.appUsers.findUnique({
            where: {
              email: email,
            },
          });

          if (!user) {
            console.log('User does not exist');
            return null;
          }

          const isPasswordValid = await confirmPasswordHash(
            authFormType,
            user.password
          );

          if (!isPasswordValid) {
            console.log('Password is not correct');
            return null;
          }

          return {
            email: user.email,
            name: `${user.firstName} ${user.lastName}`,
            firstName: user.firstName,
            lastName: user.lastName,
            id: user.id,
          };
        } catch (error) {
          console.log(`Error: ${error}`);
        }
      },
    }),
  ],
  callbacks: {
    // Called before session
    jwt: ({ token, user }) => {
      if (user) {
        return {
          ...token,
          id: user.id,
          firstName: user.firstName,
          lastName: user.lastName,
        };
      }
      return token;
    },
    // Called after jwt
    session: ({ session, token }) => {
      return {
        ...session,
        user: {
          ...session.user,
          id: token.id,
          firstName: token.firstName,
          lastName: token.lastName,
        },
      };
    },
  },
  pages: {
    signIn: '/login',
  },
  session: {
    strategy: 'jwt',
  },
};

export default NextAuth(authOptions);
cphill
  • 5,596
  • 16
  • 89
  • 182
  • is this happening on the first mount of the component ? I think because the `session` is still loading, take a look [here](https://stackoverflow.com/a/75428838/13488990) maybe it helps – Ahmed Sbai Mar 27 '23 at 23:45
  • What I ended up doing was moving the API call to the server component and got it to work. It didn't make sense to do an additional step for the GET request when the information was successfully being loaded within that component – cphill Mar 28 '23 at 00:39

0 Answers0