Cip
Cip

Reputation: 151

Why does my session only have the user's email when using next-auth with credentials?

I'm using next-auth with credentials to login users like this:

import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { connectToDb } from "@utils/database"
import User from "@models/user"
import bcrypt from "bcrypt"


export const authOptions = {
    providers: [
        CredentialsProvider({
            name: "credentials",
            credentials: {
                email: { label: "Email", type: "email", placeholder: ""},
                password: { label: "Password", type: "password", placeholder: ""}
            },

            async authorize(credentials) {
                const {email, password} = credentials
                
                try {
                    await connectToDb()

                    const user = await User.findOne({ email })

                    if(!user) {
                        return null
                    }

                    const passwordsMatch = await bcrypt.compare(password, user.password)
                    if(!passwordsMatch) {
                        return null
                    }

                    return user
                } catch (error) {
                    console.log(error)
                    return null
                }
            }
        })
    ],
    session: {
        strategy: "jwt",
    },
    
    secret: process.env.NEXTAUTH_SECRET,
    pages: {
        signIn: '/login'
    }
}

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST}

The login works, and when I console.log(user) in the auth route, it shows all the data (firstName, lastName, email, phoneNumber, _id, password) but when I go to console.log the session on the dashboard once they've logged in, the only thing the session has is the user's email. Here is my dashboard page:

'use client'

import { useSession } from 'next-auth/react'

const DashboardPage = () => {

    const { data: session, status} = useSession()
    console.log('dashboard', session)

  return (
    <div>
        <h1>Dashboard</h1>
        <h3>{session?.user?.email}</h3>
    </div>
  )
}

export default DashboardPage

Does anyone know why the session only has the email and not the firstName, lastName, etc? Or how should I be accessing them? This is what the console.log shows in the dashboard page:

dashboard 
Object { user: {…}, expires: "2023-11-24T03:18:28.585Z" }
​
expires: "2023-11-24T03:18:28.585Z"
​
user: Object { email: "[email protected]" }
​​
email: "[email protected]"
​​
<prototype>: Object { … }
​
<prototype>: Object { … }

Upvotes: 5

Views: 2363

Answers (2)

Renard Bergson
Renard Bergson

Reputation: 21

I had been searching and found what worked for me! Just do:

callbacks:{
  // the callbacks will be executed after a well done login
  async jwt ({ token, user }) {
    if (user?._id) token._id = user._id
    return token
  },
  async session ({ session, token, user }) {
      // user id is stored in ._id when using credentials provider
      if (token?._id) session.user._id = token._id
  
      // user id is stored sub ._id when using google provider
      if (token?.sub) session.user._id = token.sub

      // we'll update the session object with those 
      // informations besides the ones it already has
      return session
  },
},

PS: I'm only using "credentials" and "Google Providers" for login.

Upvotes: 2

MB&#194;Š
MB&#194;Š

Reputation: 407

in next auth the session always take only the user email by default if you want to add anything else you will have to edit the session object in the callbacks object here is an example how i did add (isAdmin and image and the id and provider) to the session in next-Auth you can change it to add whatever you want from the user objected that did get returned from data base

import NextAuth from 'next-auth'
import CredentialsProvider from "next-auth/providers/credentials"
import { sendVerificationEmail } from '../../../middleware/emailService';

import dbConnect from '../../../lib/dbConnect';
import User from '../../../models/User';
import { compare, hash } from 'bcryptjs';
import crypto from 'crypto';


import axios from 'axios';


export const authOptions = {
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      async authorize(credentials, req){

        const ress  = await axios.get('http://localhost:3000/api/ip-return')
        console.log(ress.data)
        if(ress.data.ok){
          await dbConnect()
          
          //check user existance
          const result = await User.findOne({email: credentials.email}).select('+password')
          if(!result){
            throw new Error('No user Found With Email Please Sign Up!')
          }

          if(result.verified){
            //compare password
            const checkPassword = await compare(credentials.password, result.password)
            if(!checkPassword || result.email !== credentials.email){
              throw new Error("Email or Password dosen't match")
            }

            return result
          }else{
            sendVerificationEmail(result.email, result.verificationToken)
            throw new Error("Please Confirm Your Email!")
          }
        }else{
          throw new Error(ress.data.message)
        }

      }
    })
  ],
  callbacks:{
    jwt: async ({ token, user }) =>{

      if (user) {
        token.uid = user;
      }

      return token
    },
    session: async ({ session, token }) => {
        // here we put session.useData and put inside it whatever you want to be in the session
        // here try to console.log(token) and see what it will have 
        // sometimes the user get stored in token.uid.userData
        // sometimes the user data get stored in just token.uid
        session.userData = {
          isAdmin: token.uid.userData.isAdmin,
          id: token.uid.userData._id,
          image:token.uid.userData.image,
          provider:token.uid.userData.provider
        }

      return session;
    },
  },
  strategy: "jwt",
  secret: process.env.NEXT_AUTH_SECRET,
  database: process.env.DB_URL  
}

export default NextAuth(authOptions)

Upvotes: 2

Related Questions