Next.js Discord

Discord Forum

Can't access user data in session returned by useSession()

Unanswered
Scale parasitoid posted this in #help-forum
Open in Discord
Scale parasitoidOP
Hey Guys, I am having an issues with CredentialsProvider and useSession(). When I try to access user information in session, user is a prototype object.

In the next-auth api route I console.log() the user before returning it, and it looks good. However when I do a console.log in the client to check the user data, I get Prototype. Session however looks good, I get an expiration date.

Any idea what could be wrong?

20 Replies

Scale parasitoidOP
import NextAuth from "next-auth";
import { SupabaseAdapter } from "@auth/supabase-adapter";
import jwt from "jsonwebtoken"
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
import EmailProvider from "next-auth/providers/email";
import LinkedinProvider from "next-auth/providers/linkedin"
import CredentialsProvider from "next-auth/providers/credentials";
import nextAuth from "next-auth";
import supabase from "../../../../../lib/config/supabaseClient";
import bcrypt from 'bcrypt'

export const Options  = {
    providers: [
        CredentialsProvider({
            id: 'credentials',
            name: "Credentials",
            credentials: {
                email: { label: "email", type: "email", placeholder: "jsmith@email.com" },
                password: { label: "Password", type: "password" }
              },

            async authorize(credentials, req) {
                console.log("inside authorize");
                if(!credentials.email || !credentials.password){
                    return null;
                }

                const {data: user, error} = await supabase
                    .from('users')
                    .select()
                    .eq('email', credentials.email)

                if(user.email == credentials.email){
                    return null;
                }

                const passwordMatch = bcrypt.compare(credentials.password, "10", user.hashedPassword);

                if(!passwordMatch){
                    return null;
                }

                console.log(user);
                
                return user;
                
            }
        }),
    ],
    secret: process.NEXTAUTH_SECRET,
    debug: process.env.NODE_ENV === 'development',
    pages: {
        signIn: '/signin',
    },
}

const handler = NextAuth(Options);
export { handler as GET, handler as POST};
client code

'use client'

import { useSession } from "next-auth/react";
import { redirect } from "next/navigation";
import CompanyDashboard from "@/app/components/company-dashboard";
import JobList from "../../components/job-list";
import SidebarNav from "@/app/components/sidebar-nav";
import Image from "next/image";



export default function Page() {

  const { data: session, status } = useSession({
    onUnauthenticated(){
      redirect('/signin');
    }
  })

  console.log(session);

  return (
    <>
      {session && 
          <section className="grid grid-cols-12 grid-rows-12 w-11/12 my-10 gap-3">
            <div className="flex flex-row col-span-2 items-center gap-5 ">
                <Image src={session.user.image} className=" rounded-full " width={50} height={50} alt={session.user.name}></Image>
                <h1 className="col-span-2">{session.user.name}</h1>
            </div>
            <section className="col-span-2 row-start-2 row-span-full border-r-1 border-slate-200">
                <SidebarNav className="" />
            </section>
            
            <section className="col-start-3 col-span-full row-span-full gap-5">
              <CompanyDashboard />
            {/* Job List with jobs posted by the company */}
            </section>
          </section>
      }

    </>
  )
}
You need to assign the user to the session in callbacks.

https://next-auth.js.org/configuration/callbacks#session-callback
Scale parasitoidOP
it's still returning a prototype
Can you show the code of callbacks?
Scale parasitoidOP
callbacks: {
        async session({ session, token, user }) {
            // Send properties to the client, like an access_token and user id from a provider.
            session.accessToken = token.accessToken;
            session.user.id = token.id;
            
            return session;
          }
    }
also one weird thing in useSession is that onUnauthenticated doesn't redirect me
Scale parasitoidOP
i get undefined for the user
and for token
Ok i got something now
it was because supabase return an array of objects
instead of the object itself
if I return user[0] in the authorize func, then I have data
but user inside the callback is still undefined. do you know why?
Hmm... I forget how to write it. But here is the code I used before which is working:

callbacks: {
  async jwt({ token, user }) {
    if (!user) {
      return token
    }

    return {
      ...token,
      ...user
    }
  },
  async session({ session, token }) {
    session.user.id = token.id
    // session.user.xxx = token.xxx <-- assign it as you need

    return session
  }
}
Scale parasitoidOP
Ok I checked the documentation, user is only there on case of database authentication
But I figured out what to do
I basically get the user again from database and then assign new properties to the session inside the session callback