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

Why is the type of parameter 1 not an 'HTMLFormElement', causing the failure to construct 'FormData'?

When I try to execute the code, I encounter a JavaScript error. My objective is to store the data from the form. Error Message TypeError: Failed to create 'FormData': argument 1 is not an instance of 'HTMLFormElement'. The issue arise ...

Uncovering the array within Javascript

I'm struggling to figure out why I can't access an array that PHP sends back to me. When AJAX makes a call, I send back this: $response['success'] = true; In my PHP file, I use echo json_encode($response); to send it. However, when I ...

Create a vibrant PNG image background that changes dynamically based on the dominant color of the

Is it possible to dynamically set the background color of a PNG image, either white or black, based on the dominant color in the image? For example, this image should have a dark background: https://i.stack.imgur.com/cerjn.png And this one should have a ...

Is there a way to identify and count duplicate data-items within an array, and then showcase this information using a react view?

If we have an array like this: [{id: 1, name: "chocolate bar"}, {id:2, name: "Gummy worms"}, {id:3, name:"chocolate bar"}] Is there a way to show on the dom that we have "2 chocolate bars and 1 Gummy Worms"? ...

Implementing dynamic URLs using static routing in Express

I'm looking for a way to render a page statically in Express that involves using a dynamic URL. For example, In my forum, users create posts and each post has its unique URL that shows the post when clicked: localhost:8080/posts/postNumber Current ...

What is the best way to retrieve dynamic content from a .txt file and have it displayed on multiple HTML pages as they are loaded dynamically?

I have a file named 'm_data.txt' stored on the server that contains a continuous total of 77 (for instance). The total gets updated via a push.php page that writes to the .txt file. <!DOCTYPE html> <html> <head> <title> ...

Using Selenium and Python to scrape text from a continuously refreshing webpage after each scroll

Currently, I am utilizing Selenium/python to automatically scroll down a social media platform and extract posts. At the moment, I am gathering all the text in one go after scrolling a set number of times (see code below), but my objective is to only gathe ...

Adjust the appearance of an element in a different parent when hovering over a specific element with a matching index

I have implemented a menu on my site in two different ways - one using text and the other using pictures. Users can click on both types of menus. Now, I am looking to create an interactive feature where hovering over a specific item in the text menu (such ...

What is causing my Bootstrap Controls to malfunction?

I'm trying to create a Bootstrap carousel that shows 3 items at once and includes controls to switch between them. The carousel I've made does display the three items, but for some reason, the controls are not responding when clicked. I'm un ...

Sending a JavaScript variable to a Flask url_for function

There is an endpoint that requires a value in the URL and then generates content to be displayed within a specific div. I'm trying to construct the URL using url_for with a JavaScript variable, but it seems that $variable1 is being treated as a string ...

What steps should I follow to install nodemon on my Windows 10 device?

Currently, I am utilizing the bash console on my Windows 10 system. My goal is to install nodemon using node.js, but when attempting to do so, I encounter this error message: sudo: npm: command not found It's puzzling because I should already have n ...

Reset the AJAX object using jQuery

Currently, my code looks like this: object1 = $.ajax({ .. .. }); If an error occurs, I would like to have the ability to restart the ajax request. For instance, if the user's connection is lost, I want to be able to easily call the same ajax again w ...

Generating a client-side MD5 hash for an image file in order to compare it to the hash calculated by Firebase?

Is there a way to calculate the MD5 of an image file on the client side within my Angular Map application, that will match the MD5 when I store the file on Firestore? I need to verify that a user's file matches a reference version stored in Firebase ...

Error encountered when using prisma findUnique with where clause

Trying to set up a Singup API using ExpressJS and Prisma is proving to be a bit challenging. The issue arises when I attempt to verify if a given email already exists in my database. Upon passing the email and password, an error is thrown stating Unknown ...

How to format numbers with commas in AngularJS to make them easier to read

One of my variables looks like this: $scope.numbers = 1234567. When I apply the filter {{numbers| number : 0}}, the result is 1,234,567. Is it possible to get a result like 12,34,567 instead? Thank you in advance. ...

I am looking to optimize my WordPress posts to load in increments as the user scrolls down the page, similar to how Facebook does

I am looking to implement a feature on my WordPress post where the content loads a few at a time as the user scrolls, similar to Facebook. Specifically, I would like my webpage to automatically load 10 posts and then continue loading 10 more as the user re ...

Sending data from TextBox as json format

JavaScript Code: var latitude = document.getElementById("<%=txt_Lat.ClientID %>").value; var longitude = document.getElementById("<%=txt_Long.ClientID %>").value; var jsonData = {latitude: latitude, longitude: longitude}; var jsonString = JSO ...

show tab focus outline only

In search of a straightforward and effective method for focusable elements to display an outline only when the tab key is pressed, without showing it when using a mouse in React applications. (looking for something similar to :focus-visible that function ...

Using routes with optional parameters can inhibit the loading of other routes

In my Node.js app based on Express, I have implemented three different routes. app.get('/', function (req, res) { // }) app.get('/findOne', function (req, res) { // }) app.get('/getFour', function (req, res) { // }) Init ...

Avoiding layout shift when a button is clicked in React JS

I am working on a Drawer example and following the instructions provided at https://mui.com/material-ui/react-drawer/ Everything is functioning as expected, but I am encountering an issue where my content shifts to the right when the drawer opens, and ret ...