I'm working on a Next.js application with authentication handled by a separate Node.js API deployed on Heroku. My goal is to use NextAuth.js for managing user sessions in the frontend, where the backend API handles login and returns a JWT token. However, I'm encountering issues during the login process using NextAuth.js with my custom credentials provider.
When I attempt to log in, I am unexpectedly redirected to http://localhost:3000/api/auth/error, despite setting redirect: false in my signIn method. Additionally, I am not able to successfully log in.
Upon investigation, when I checked my API logs, it did not show that any request was made to the login route for some reason. This happens even after replacing the environment variable name with the actual route name.
Below is my folder structure:

Here's the expected response from my API upon successful login:
{
"user": {
"location": {
"city": "Bradford, UK",
"lat": 53.7937996,
"lng": -1.7563583
},
"_id": "659f77b9eaee64fce34d9083",
"fullName": "opeyemi david odedeyi",
"email": "[email protected]",
"gender": "prefer not to say",
"isEmailConfirmed": false,
"isActive": true,
"createdAt": "2024-01-11T05:08:09.359Z",
"updatedAt": "2024-01-13T04:35:40.948Z",
"uniqueURL": "opeyemi-david-odedeyi-1704949689359",
"__v": 3
},
"token": "<JWT_TOKEN>",
"message": "User logged in successfully"
}
Below is the code for my login page in the Next.js app:
import { useState } from 'react';
import { signIn } from 'next-auth/react';
export default function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const buttonClicked = async (e) => {
e.preventDefault();
const result = await signIn('credentials', {
redirect: false,
email,
password
});
if (result.error) {
console.log(result.error);
} else {
console.log(result);
}
};
// ... JSX for form inputs ...
return (
// ... JSX for the login form ...
);
}
And here is my [...nextauth].js configuration:
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
export default NextAuth({
providers: [
CredentialsProvider({
name: 'credentials',
authorize: async (credentials) => {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/login`, {
method: 'POST',
body: JSON.stringify(credentials),
headers: { "Content-Type": "application/json" }
});
const user = await res.json();
if (!res.ok) {
throw new Error(user.message || "Something Went wrong!!");
}
return user;
}
})
],
callbacks: {
jwt: async ({ token, user }) => {
if (user) {
token.accessToken = user.token;
}
return token;
},
session: async ({ session, token }) => {
session.accessToken = token.accessToken;
return session;
}
},
});
I'm not sure why I'm being redirected to the error page and why the login isn't successful, and why is no request made to my login route via the api logs. Is there something I'm missing in my NextAuth.js setup or the way I'm handling the login process? Any insights or suggestions would be greatly appreciated.
The code looks good to me. Could you check the terminal to see if there's any error from the Next.js app?
Also, add logs into authorize, and the callbacks to check if you receive exactly what you expect.
One side thing, which is not a problem, the NextAuth route runs in the server, so optionally you could you a non-client exposed environment variable instead of process.env.NEXT_PUBLIC_API_URL (just remove NEXT_PUBLIC to make it server-only).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With