Next.js Discord

Discord Forum

Error in getServerSession in Next-auth

Answered
Santhosh Prabhakaran posted this in #help-forum
Open in Discord
I'm getting the server session from the next-auth in nextjs app. When I run this code,

export default async function RootLayout({ children }) { const session = await getServerSession(authOptions); const router = useRouter(); return ( <html lang="en"> <body className={inter.className}> <AuthProvider> {session ? ( <div className="flex flex-row h-screen w-full mx-auto"> <SideBar /> {children} <AsideBar /> </div> ) : ( router.push("/") )} </AuthProvider> </body> </html> ); }

I'm getting this error,

Why this error is coming ? Any help on this would be appreciated.
Answered by Cape horse mackerel
You can't use useRouter wihin server components and the RootLayout is a server component
View full answer

35 Replies

Cape horse mackerel
You can't use useRouter wihin server components and the RootLayout is a server component
Answer
Ohh!, Thank you got it.
@Santhosh Prabhakaran Ohh!, Thank you got it.
to add to NuDg3's answer, you should use redirect() for this
Instead of useROuter ?
yes; useRouter is a client-side hook, you can't use it in server components
Okay, thanks!
@joulev I'm having another doubt. In this next-auth code,
import { MongoClient } from "mongodb";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";
import NextAuth from "next-auth/next";

export const authOptions = {
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Email" },
        password: {
          label: "Password",
          type: "password",
          placeholder: "Password",
        },
      },
      async authorize(credentials, req) {
        try {
          const client = await MongoClient.connect(process.env.MONGO_URL, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
          });
          const db = client.db("test");
          const user = await db
            .collection("users")
            .findOne({ email: credentials.email });

          if (!user) throw new Error("User is not found!");

          if (user) {
            const checkPassword = await bcrypt.compare(
              credentials.password,
              user.password
            );
            if (!checkPassword) throw new Error("Password is incorrect!");
          }

          return {
            user: {
              
            },
          };
        } catch (error) {
          throw new Error(error);
        }
      },
    }),
  ],
};

const handler = NextAuth(authOptions);
export { handler as POST, handler as GET };
I can't able to send the session object as the desired data. It only allows email and name. Why ?
@Santhosh Prabhakaran <@484037068239142956> I'm having another doubt. In this next-auth code, import { MongoClient } from "mongodb"; import CredentialsProvider from "next-auth/providers/credentials"; import bcrypt from "bcrypt"; import NextAuth from "next-auth/next"; export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email", placeholder: "Email" }, password: { label: "Password", type: "password", placeholder: "Password", }, }, async authorize(credentials, req) { try { const client = await MongoClient.connect(process.env.MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true, }); const db = client.db("test"); const user = await db .collection("users") .findOne({ email: credentials.email }); if (!user) throw new Error("User is not found!"); if (user) { const checkPassword = await bcrypt.compare( credentials.password, user.password ); if (!checkPassword) throw new Error("Password is incorrect!"); } return { user: { }, }; } catch (error) { throw new Error(error); } }, }), ], }; const handler = NextAuth(authOptions); export { handler as POST, handler as GET }; I can't able to send the session object as the desired data. It only allows email and name. Why ?
i havent used next-auth for a very long time so cant help you here. also this issue is unrelated to the question, so i suggest you make a new forum post specifically for this issue or go to #next-auth so that people knowing the library can go and help
@alfon where did you send the session object
To the client side's session
@Santhosh Prabhakaran To the client side's session
what is the desired data?
and what appeared instead?
@alfon what is the desired data?
The "user" object I obtained from the db
i think you need to transform the sesion object in the callbacks
if u use jwt then u need to change it in jwt() callback and session() callback
if you don't use jwt and use db/adapter then u need to transform ur session object in session() callback
I'm trying like this but the session comes as null,
export const authOptions = {
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Email" },
        password: {
          label: "Password",
          type: "password",
          placeholder: "Password",
        },
      },
      async authorize(credentials, req) {
        try {
          const client = await MongoClient.connect(process.env.MONGO_URL, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
          });
          const db = client.db("test");
          const user = await db
            .collection("users")
            .findOne({ email: credentials.email });

          if (!user) throw new Error("User is not found!");

          if (user) {
            const checkPassword = await bcrypt.compare(
              credentials.password,
              user.password
            );
            if (!checkPassword) throw new Error("Password is incorrect!");
          }

          return {
            id: 1,
            name: user.username,
            email: user.email,
          };
        } catch (error) {
          throw new Error(error);
        }
      },
    }),
  ],
  callbacks: {
    session: async (session, user) => {
      session.user.id = user._id;
      session.name = user.name;
      session.username = user.username;

      Promise.resolve(session);
    },
  },
};
@alfon
return session...
not sure where you got that promise.resolve(session) from
also can you use ```js
I've changed the callbacks like this,
callbacks: {
    async(session, user) {
      session.user.id = user._id;
      session.name = user.name;
      session.username = user.username;
      session.email = user.email;
      return session;
    },
  },
still only returns the name and email.
@alfon which callback is that?
import { MongoClient } from "mongodb";
import CredentialsProvider from "next-auth/providers/credentials";
import bcrypt from "bcrypt";
import NextAuth from "next-auth/next";

export const authOptions = {
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Email" },
        password: {
          label: "Password",
          type: "password",
          placeholder: "Password",
        },
      },
      async authorize(credentials, req) {
        try {
          const client = await MongoClient.connect(process.env.MONGO_URL, {
            useNewUrlParser: true,
            useUnifiedTopology: true,
          });
          const db = client.db("test");
          const user = await db
            .collection("users")
            .findOne({ email: credentials.email });

          if (!user) throw new Error("User is not found!");

          if (user) {
            const checkPassword = await bcrypt.compare(
              credentials.password,
              user.password
            );
            if (!checkPassword) throw new Error("Password is incorrect!");
          }

          return {
            id: 1,
            name: user.name,
            email: user.email,
          };
        } catch (error) {
          throw new Error(error);
        }
      },
    }),
  ],
  callbacks: {
    async(session, user) {
      session.user.id = user._id;
      session.name = user.name;
      session.username = user.username;
      session.email = user.email;
      return session;
    },
  },
};

const handler = NextAuth(authOptions);
export { handler as POST, handler as GET };
ya which callback is that?
it doesn't have a name
Name ? Sorry I don't get it
like is it a jwt() callback, is it a session() callback
signIn() callback
session callback
then it should be session: async () => {} or async session() {}
its not correct syntax
It returns only the name and email. Is it because I already returned the user above in providers config ?
Im not entirely sure but you have to return the session object properly in the session() callback