next-auth
next-auth copied to clipboard
Unexpected Modification of User Object in Next.js Authentication Callback
Environment
I'm facing an issue with user authentication in a Next.js application using NextAuth. I have implemented a custom signIn callback for Google OAuth authentication, where I check if the user exists in the database and return it if found. However, I'm encountering unexpected behavior where the user object seems to be modified or overwritten.
Example in Database i have already have record name : ijk email : [email protected]
when i use google login, name : abc email : [email protected]
since the email already exists it should return {name: ikj, email: [email protected]} instead it returns {name : abc, email : [email protected]}, which is an unexpected behaviour. {name : abc, email : [email protected]} this getting stored in authprovider and in backend returns the status code of 401
async signIn is the main fucntion of google outh
Reproduction URL
https://github.com/loki4514/Blog-App
Describe the issue
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
name: "crendentials",
credentials: {},
async authorize(credentials, req): Promise<any> {
const { email, password } = credentials as {
email: string;
password: string;
};
try {
const user = await User.findOne({ email })
if (!user) {
// Assuming you have access to the response object 'res'
return null
}
const comparedpassword: boolean = await bcryptjs.compare(password, user.password)
if (!comparedpassword) {
return null
}
return user;
} catch (error: any) {
console.log("Error:", error)
return null
}
}
}),
GoogleProvider({
clientId: GOOGLE_CLIENT_ID! as string,
clientSecret: GOOGLE_CLIENT_SECRET! as string
})
],
session: {
strategy: 'jwt'
},
callbacks: {
async signIn({ user, account }: { user: any; account: any }) {
if (account.provider === "google" && user) {
try {
const { name, email }: { name: string; email: string } = user;
const existingUser = await User.findOne({ email });
if (existingUser) {
return existingUser; // Return existing user
}
const newUser = new User({
name: name,
email: email,
isVerified: true
});
const savedUser = await newUser.save();
return savedUser; // Return the newly created user
} catch (error) {
console.error("Error in Google OAuth signIn callback:", error);
return null;
}
}
else {
// not hiting the else block
console.log("why is i'm getting called here")
return user;
}
},
async jwt({ token, user }) {
if (user) {
console.log(user,"this failed in every aspect of my life 0001")
// i should existingUser object but i'm not getting it
token.email = user.email
token.name = user.name
token.id = user.id
}
if (!user)
token.error = "Invalid Credentials"
token.errorStatus = 401; // Set error status code
}
return token
},
async session({ session, token }: { session: any, token: any }) {
if (session.user) {
session.user.email = token.email;
session.user.name = token.name;
session.user.id = token.id;
}
return session
}
},
secret: process.env.NEXTAUTH_SECRET!,
pages: {
signIn: '/login'
}
}
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }`
How to reproduce
Currently i working in local repository
Expected behavior
Despite returning the existing user if found, the user object appears to be modified, causing inconsistencies in authentication. I've ensured that there are no explicit variable reassignments within the callback function.
I've tried debugging the issue, but I'm unable to identify the root cause. Could someone please help me understand why the user object is being modified unexpectedly and suggest how to resolve this issue?
Any insights or suggestions would be greatly appreciated. Thanks in advance!
here is stackoverflow question Link
You should retrieve the user in the jwt callback with token.email. Then you can use it to set the token entries.