nextauthjs / nextauthjs/next-auth

Credentials Provider Not Firing Session Callback

Open
#3,970 27 comments 15 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

adapters prisma triage
Dominant language
TypeScript
Stars
28.4k
Forks
4k
PR merge metrics
No merged PRs in 30d

Description

Description 🐜

Hello,

I'm having trouble with using Credentials Provider where it's not firing the session callback. I've logged the whole process from signin and output with logger functionality.

I'm not sure if it's my [..nextauth] setting or it's a bug within next-auth and prisma adapter.

Can provide the repo link if needed.

Please note that Github Provider are working fine where it generate session token.

Is this a bug in your own project?

Yes

How to reproduce ☕️
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import GitHubProvider from 'next-auth/providers/github';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { PrismaClient } from '@prisma/client';

import { verifyPassword, hashPassword } from '@functionHelpers/auth/passwords';

const prisma = new PrismaClient();

export default NextAuth({
	adapter: PrismaAdapter(prisma),
	secret: process.env.NEXTAUTH_SECRET,
	// session: {
	// 	jwt: true,
	// },
	pages: {
		// signIn: '/auth/signin',
		// signOut: "/auth/logout",
		// error: "/auth/error", // Error code passed in query string as ?error=
	},
	logger: {
		error(code, metadata) {
			console.log({ type: 'inside error logger', code, metadata });
		},
		warn(code) {
			console.log({ type: 'inside warn logger', code });
		},
		debug(code, metadata) {
			console.log({ type: 'inside debug logger', code, metadata });
		},
	},
	providers: [
		GitHubProvider({
			clientId: process.env.GITHUB_CLIENT_ID,
			clientSecret: process.env.GITHUB_CLIENT_SECRET,
		}),
		CredentialsProvider({
			id: 'app-login',
			name: 'App Login',
			credentials: {
				firstName: {
					label: 'First Name',
					type: 'text',
				},
				lastName: {
					label: 'last Name',
					type: 'text',
				},
				email: {
					label: 'Email Address',
					type: 'email',
				},
				password: {
					label: 'Password',
					type: 'password',
				},
			},
			async authorize(credentials, req) {
				console.log('Starting the signup/login process ---');
				try {
					let maybeUser = await prisma.user.findFirst({
						where: {
							email: credentials.email,
						},
					});

					// register process calling
					if (credentials.methodType === 'register') {
						if (!maybeUser) {
							if (
								!credentials.password ||
								!credentials.email ||
								!credentials?.firstName ||
								!credentials.lastName
							) {
								throw new Error('Please fill all of the information');
							}

							maybeUser = await prisma.user.create({
								data: {
									name: `${credentials.firstName} ${credentials.lastName}`,
									firstName: credentials.firstName,
									lastName: credentials.lastName,
									email: credentials.email,
									password: await hashPassword(credentials.password),
								},
							});
						} else {
							throw new Error('User already existed, please login.');
						}
					} else {
						// login process calling
						// user existed, need to verify user credentials

						if (!maybeUser) {
							throw new Error('No user found. Please create one');
						}

						if (!credentials.password || !credentials.email) {
							throw new Error('Please fill out all of the information');
						}

						const isValid = await verifyPassword(
							credentials?.password,
							maybeUser.password
						);
						if (!isValid) {
							throw new Error('Invalid Credentials');
						}
					}

					console.log('Ending the signup/login process ---');

					return maybeUser;
				} catch (error) {
					console.log(error);
					throw error;
				}
			},
		}),
	],
	callbacks: {
		async signIn({ user, account, profile, email, credentials }) {
			console.log('fire signin Callback');
			return true;
		},
		async redirect({ url, baseUrl }) {
			console.log('fire redirect Callback');
			return baseUrl;
		},
		async session({ session, user, token }) {
			console.log('fire SESSION Callback');
			return session;
		},
		async jwt({ token, user, account, profile, isNewUser }) {
			console.log('fire jwt Callback');

			// console.log({ token, user, account, profile, isNewUser });
			return token;
		},
	},
});

Screenshots / Logs 📽

Starting the signup/login process ---
Ending the signup/login process ---
fire signin Callback
fire jwt Callback
fire redirect Callback
{
  type: 'inside debug logger',
  code: 'adapter_getSessionAndUser',
  metadata: {
    args: [
      'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..MLqO5WWIQ3nyCWSw.9EZyGxkX-5tWPQbfhDCcU_KzEvgt1EDKSEnC_px8RZ6q_Np8EfBYPIMVkBbgDkc7DdBRp3vssSAUWnNNoqjdvWlstqDQZ44roLQR-IUcYaWaOZQzH_Urau6gp6SluL9J2F69_eXnMSCtqT8h6sWzgtfaX4duZ1e6T49ryZr7qZmUHURYGK5Fxgnls4xHjtWEP7VZdZV_aLqIhAD5ZQ2HSmAjOWOgWUl8NoLhrWQoLSoD0g.TmT2wjs_7lhHifh2Er_kUg'   
    ]
  }
}
fire redirect Callback

Environment 🖥

Windows 11

Contributing 🙌🏽

Yes, I am willing to help solve this bug in a PR

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied NextAuth configuration, especially the CredentialsProvider authorize entry point and the signIn, jwt, redirect, and session callbacks. Reproduce the login flow using the shown logger output and determine why the session callback is not reached; done means the expected callback behavior is explained and verified for the Credentials Provider without breaking the working GitHub Provider.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, typescript
Domain
authentication
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.