Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble Implementing Custom Login with next-auth, and getting redirected to api/auth/error

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:

enter image description here

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.

like image 721
Opeyemi Odedeyi Avatar asked Dec 21 '25 06:12

Opeyemi Odedeyi


1 Answers

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).

like image 185
Luca Restagno Avatar answered Dec 23 '25 18:12

Luca Restagno