Reputation: 151
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
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
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