The authentication protocol, Next Auth, consistently provides a 200 status response for the signIn function

I ran into a challenge while building my custom login page using Next Auth. The issue arises when I try to handle incorrect login data. If the login credentials are correct, I am able to successfully send JWT and redirect to /dashboard. However, when the login data is incorrect, returning an error message to the login page proves to be tricky. Even though the error property changes, the response status remains as 200, indicating no error. I currently rely on the error property to display the error message:

Login Page:

const Login = () => {
    const router = useRouter();
    const [loginError, setLoginError] = useState();

    const handleLogin = async (e) => {
        e.preventDefault();

        const login = e.target[0].value;
        const password = e.target[1].value;

        if (login.length && password.length) {
            const res = await signIn("credentials", {
                login,
                password,
                redirect: false,
            });
            if (res.error) setLoginError(true);
            if (!res.error) router.push("/dashboard");
        }
    };

    return (
        <div className={styles.login}>
                <form onSubmit={handleLogin} className={styles.form}>
                    <h2 className={styles.header}>Login</h2>
                    <input
                        type="text"
                        placeholder="Login"
                        className={styles.input}
                    />
                    <input
                        type="password"
                        placeholder="Password"
                        className={styles.input}
                    />
                    <button className={styles.button}>Log in</button>
                </form>
                {loginError && <div>ERROR</div>}
        </div>
    );
};

export default Login;

Route:

export const authOptions = {
    providers: [
        CredentialsProvider({
            id: "credentials",
            type: "credentials",

            credentials: {
                login: {
                    label: "login",
                    type: "text",
                },
                password: { label: "Password", type: "password" },
            },
            async authorize(credentials) {
                try {
                    await connect();
                    const user = await User.findOne({
                        login: credentials.login,
                    });
                    if (!user) return null;

                    const isPasswordValid = await bcrypt.compare(
                        credentials?.password,
                        user?.password
                    );

                    if (isPasswordValid) {
                        const { password, _id: id, ...userRest } = user?._doc;
                        const userWithoutPassword = { id, ...userRest };

                        const accessToken = signJwtAccessToken({
                            userWithoutPassword,
                        });

                        return { ...userWithoutPassword, accessToken };
                    } else {
                        return null;
                    }
                } catch (error) {
                    return new NextResponse("Database Error", { status: 500 });
                }
            },
        }),
    ],
    callbacks: {
        async jwt({ token, user }) {
            return { ...token, ...user };
        },

        async session({ session, token }) {
            session.user = token;
            session.accessToken = token.accessToken;
            return session;
        },
    },
    pages: {
        signIn: "/login",
    },
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

Would returning {status: 401, ok: false} be a better approach? This is something to consider for handling errors in the login process.

Answer №1

There seems to be an issue with NextAuth according to this report, but fret not as a clever solution has been found.

Answer №2

In the scenario where the data is invalid, you are currently returning null. It's important to note that null !== Error; thus, you should throw an error if the data is found to be invalid.

An example implementation could look something like this:

try {
    await connect();
    const user = await User.findOne({
        login: credentials.login,
    });
    if (!user) throw new Error('Invalid credentials');

    const isPasswordValid = await bcrypt.compare(
        credentials?.password,
        user?.password
    );

    if (isPasswordValid) {
        const { password, _id: id, ...userRest } = user?._doc;
        const userWithoutPassword = { id, ...userRest };

        const accessToken = signJwtAccessToken({
            userWithoutPassword,
        });

        return { ...userWithoutPassword, accessToken };
    } else {
        throw new Error('Invalid credentials');
    }
} catch (error) {
    return new NextResponse("Database Error", { status: 500 });
}

Answer №3

In my application's root directory, specifically at the node_modules level, I decided to create a new folder called patches. Inside this folder, I added a file named next-auth+4.22.1.patch and pasted in the necessary code as per the workaround provided. However, upon running npx patch-package next-auth, I encountered the following response:

PS C:\Users\iktor\Desktop\system> npx patch-package next-auth patch-package 7.0.0 Creating temporary folder Installing [email protected] with npm Diffing your files with clean files ⁉️ Not creating patch file for package 'next-auth' ⁉️ There don't appear to be any changes.

Despite these steps, the file

/node_modules/next-auth/next/index.js
remained unchanged, indicating that the update did not take effect. It should be noted that I am using version ^4.22.1 of next-auth.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

cssclassName={ validatorState === RIGHT ? 'valid' : 'invalid' }

Is there a way to dynamically add different classes based on validation outcomes in React? My current implementation looks like this: className={ validatorState === RIGHT ? 'ok' : 'no' } However, I also need to handle cases where the ...

Error: Type '() => () => Promise<void>' is not compatible with type 'EffectCallback'

Here is the code that I'm currently working with: useEffect(() => { document.querySelector('body').style['background-color'] = 'rgba(173, 232, 244,0.2)'; window.$crisp.push(['do', 'ch ...

What is the best way to accurately determine an element's location after scrolling to it?

I'm currently working on pinpointing the location of a specific element on a webpage once it has been scrolled to using JavaScript. Queries: How can I precisely determine the position of an element post-scroll? What are some common errors or extra st ...

trouble with synchronizing multiple requests in node express mysql

An expressJS endpoint is connected to a mysql DB, where a query retrieves a set of data and assigns the first returned result to a user by updating a field with the user id. The rule is that a single row can only be allocated to one user until the user pr ...

Avoiding the insertion of duplicates in Angular 2 with Observables

My current issue involves a growing array each time I submit a post. It seems like the problem lies within the second observable where the user object gets updated with a new timestamp after each post submission. I have attempted to prevent duplicate entr ...

Top method for creating integration tests in React using Redux and Enzyme

Currently, I am working on setting up integration tests within my application. There are a few API calls that occur both when the component mounts and upon a button click. The response from these API calls is stored in the app's store, which then upd ...

Tips for executing nodemon and forever in the background

Good morning! Having an issue with my node.js server running in the background. I came across this helpful thread on Stack Overflow which suggested using Forever + Nodemon together I like the concept, however, when I implement it as shown here: forever ...

Modify x and y axes in highcharts for stacked columns

Can anyone assist me in finding charts similar to the one shown below? I am interested in utilizing the stacked column charts provided by the highcharts library. However, I need to modify the presentation of the data values as demonstrated in the image. I ...

What is the most effective way to add images to a table using JavaScript?

Is there a way to insert images into the "choicesDiv" without having to make changes to the HTML & CSS? Here is the table code: <table id="choices"> <tr> <td><div class="choicesDiv" value="1"></div></td> ...

Trouble with NodeJS async/await - navigating through function arguments

Currently, I am attempting to perform web scraping using a particular library while implementing Node's async/await method in my code. Within the function named 'sayhi', I have created a variable 'page' and encountered an issue wh ...

How come my directive is being updated when there are changes in a different instance of the same directive?

For the purpose of enabling Angular binding to work, I developed a straightforward directive wrapper around the HTML file input. Below is the code for my directive: angular.module('myApp').directive('inputFile', InputFileDirective); f ...

Im testing the creation of a global style using styled-components

Is there a way to create snapshot tests for styled-components with createGlobalStyle? The testing environment includes jest v22.4.4, styled-components v4.1.2, react v16.7, jest-styled-components v5.0.1, and react-test-renderer v16.6.3 Currently, the outp ...

display different vue component based on screen size

I am in search of a method to implement responsive components in Vue.js (Nuxt). I have developed this mix-in but encountering an error: export const mediaQuery = { data() { return { breakpoints: { sm: 576, md: 768, lg: ...

Clicking on the initial link will in turn prompt clicks on the subsequent links

Can you please provide instructions on how to correctly simulate a click on the remaining links if a click is made on the first link? jQuery('a.one_num').click(function() { jQuery('a.two_num').click(); jQuery('a.three_num&ap ...

Executing secure journey within TypeScript

Just came across an enlightening article on Medium by Gidi Meir Morris titled Utilizing ES6's Proxy for secure Object property access. The concept is intriguing and I decided to implement it in my Typescript project for handling optional nested object ...

Tips for incorporating a multimedia HTML/JavaScript application within C++ programming

I possess the source code for a JavaScript/HTML5 application that operates on the client-side and manages the transmission/reception of audio and video data streams to/from a server. My objective is to develop a C++ application that fully integrates the c ...

"Oops, it seems like there are an excessive number of connections in Express MySQL causing

While programming in Angular and creating an API server in Express, I encountered a minor issue after spending hours coding and making requests to the API. The problem arises when the maximum number of requests is reached, resulting in an error. Everythin ...

Vue email validation is failing to return a valid email address

I'm relatively new to Vue and have implemented email validation using the reg expression in my Vue script data for this project. By utilizing console.log(this.reg.test(this.email)) and observing the output while users input their email, the validation ...

Following mouse element delay issue in the latest directory of a Next.js 13 application

I'm working on a project where I want to create an element that follows the mouse as it moves across the screen. I decided to use framer motion for the animation and found a helpful example in their documentation: Check out this example from framer mo ...

Encountering an Issue when Registering New Users in Database using Next.js, Prisma, and Heroku

Currently, I am immersed in my inaugural full-stack app development project, which is aligning with an online course. Unfortunately, I have encountered a major stumbling block that has persisted despite hours of troubleshooting. The issue arises when I try ...