Search code examples
next.jsnext-auth

How can I fix the 'CLIENT_FETCH_ERROR' in Next Auth Google login with getSession function?


I am currently building a next js application. I am implementing Next Auth google login. I have completed this step and the session is successfully retrieved in the end. The problem arises when the getSession function is used in the backend. It throws the given error.

[next-auth][error][CLIENT_FETCH_ERROR] 
https://next-auth.js.org/errors#client_fetch_error undefined {
  error: {},
  url: 'http://localhost:3000/api/auth/session',
  message: undefined
}

Below is some code used - this is the app definition:

const App = ({
  Component,
  pageProps: { session, ...pageProps },
}: AppPropsWithLayout) => {
  usePageViews();
  const getLayout = Component.getLayout || ((page) => page);
  const [context, setContext] = useState({
    image: null,
  });
  const router = useRouter();
  useEffect(() => {
    console.log('URL: ', router.asPath);
    // if (!session) {
    //   router.push('/');
    // }
  }, [router]);

Here is the google login section:

import { NextApiHandler } from "next";
import NextAuth from "next-auth";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import GoogleProvider from "next-auth/providers/google";
import EmailProvider from "next-auth/providers/email";
import prisma from "lib/prisma";
import { sendSignUpEmail } from "lib/sendgrid";
import { sendSignInNotification } from "lib/integromat";

const authHandler: NextApiHandler = (req, res) => {
  return NextAuth(req, res, options);
};

export default authHandler;

const options = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    EmailProvider({
      server: {
        host: process.env.SMTP_HOST,
        port: Number(process.env.SMTP_PORT),
        auth: {
          user: process.env.SMTP_USER,
          pass: process.env.SMTP_PASSWORD,
        },
      },
      from: process.env.SMTP_FROM,
    }),
  ],
  adapter: PrismaAdapter(prisma),
  secret: process.env.NEXTAUTH_SECRET,
  pages: {
    signIn: "/signin",
    verifyRequest: "/verify-request",
  },

  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      if (email?.verificationRequest) {
        return true;
      }
      const result = await prisma.user.findUnique({
        where: {
          email: user.email,
        },
      });
      let isNewUser = false;
      if (!result) {
        isNewUser = true;
        sendSignUpEmail(user.email);
      }
      const dto = {
        user,
        account,
        profile,
        isNewUser,
      };
      sendSignInNotification(dto);
      return true;
    },
  },
};

And finally where the error occurs:

import { getSession } from "next-auth/react";
import prisma from "lib/prisma";

async function handler(req, res) {
  const { query, method, body } = req;
  console.log("came here");
  const session = await getSession({ req });
  console.log(session);
  switch (method) {
    case "POST":
      if (!session) {
        res.status(401).json({ error: "You are not authenticated" });

I shared only necessary amount should be sufficient to determine the issue. I am losing my mind. Couldn't figure it out. Any ideas?

The problem is that 1. The url used in the .env file is not api/auth/session. I don't know if it calls that automatically but from the sources I have seen, I doubt so. The solutions tried were given as such:

  • Cache cleanup on browser and use of incognito in case of a cache problem.
  • NEXTAUTH_URL and NEXTAUTH_SECRET have been defıned. The secret is a base 64 created by the use of openssl, next auth url is http://localhost:3000
  • Deleted the next file in the directory to try to override the url.
  • Computer restarted

Couldn't solve it after here. Didn't know where to go.


Solution

  • use getServerSession. I saw a lot of examples are using getSession, so I assume nextauth supported you to do it in older version. But with newer version, getServerSession is recommended. Maybe you need some addtional work to make getSession in backend. In you api, you can do:

    const session = await getServerSession(context.req, context.res, authOptions)
    

    enter image description here