next-auth: Crendtials provider with redirect:false - next-auth/react signIn returns status:200 ok:true with failed authentication.

Provider type

Credentials

Environment

Using dockerised environment FROM node:18-alpine so

  • node 18 latest,
  • next 13.4.1
  • next-auth 4.22.1
  • react 18.2

Reproduction URL

https://github.com/OdifYltsaeb/next-auth-bug-report

Describe the issue

I’m following the most basic setup described here https://medium.com/@tom555my/strapi-next-js-email-password-authentication-a8207f72b446 and the next-auth/react signIn (see console.log('stuff in handlesubmit', stuff); in the code below) resolves into { error: "CredentialsSignin", status: 200, ok: true, url: null } when authentication fails due to incorrect email/password. The strapi request returns with error 400, and thus the error message in the object that singIn resolves to, but the status is 200, while it should probably be something else.

// app/api/auth/[…nextauth]/route.js

import NextAuth from 'next-auth';
import { authOptions } from '../../../../lib/auth';

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

// lib/auth.js

import CredentialsProvider from "next-auth/providers/credentials";
import axios from "../utils/axios";

const signIn = async function({ email, password }) {
    const res = await axios.post(`${process.env.STRAPI_URL}/api/auth/local`, {
        identifier: email,
        password
    });
    return res;
};

const authOptions = {
    session: {
        strategy: "jwt"
    },
    providers: [
        CredentialsProvider({
            name: "Sign in with Email",
            credentials: {
                email: { label: "Email", type: "text" },
                password: { label: "Password", type: "password" }
            },
            async authorize(credentials, req) {
                if (credentials == null) return null;
                try {
                    const { user, jwt } = await signIn({
                        email: credentials.email,
                        password: credentials.password
                    });
                    return { ...user, jwt };
                } catch (error) {
                    console.log('FAIL!', Object.keys(error));
                    // Sign In Fail
                    return null;
                }
            }
        })
    ],
    callbacks: {
        session: async ({ session, token }) => {
            session.id = token.id;
            session.jwt = token.jwt;
            return Promise.resolve(session);
        },
        jwt: async ({ token, user }) => {
            const isSignIn = user ? true : false;
            if (isSignIn) {
                token.id = user.id;
                token.jwt = user.jwt;
            }
            return Promise.resolve(token);
        }
    }
};

export { authOptions, signIn };

// components/forms/LoginForm.js

...
import { signIn } from 'next-auth/react';
...

const LoginForm = withFormik({
    mapPropsToValues: () => ({
        email: '',
        password: '',
    }),
    validationSchema: Yup.object().shape({
        email: Yup.string().email('Invalid email address').required('Email is required'),
        password: Yup.string().required('Password is required'),
    }),

    handleSubmit: async (values, { props, ...formik }) => {
        await signIn('credentials', {
            redirect: false,
            email: values.email,
            password: values.password,
        }).then((stuff) => {
            console.log('stuff in handlesubmit', stuff);
        });
    },

    displayName: 'LoginForm', // helps with React DevTools
})(Login);

How to reproduce

  • clone project, make sure you have docker + docker compose and make commands available
  • use make build-dev to set stuff u p
  • use make start-dev to run docker compose
  • navigate to http://localhost:8000/login
  • open console
  • enter random email and password and observe the console printout.

Expected behavior

I would expect that the status is not OK and code is not 200.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 16
  • Comments: 22 (4 by maintainers)

Most upvoted comments

I ran into the exact same issue. As far as I can tell, this is happening only under the app router.

I fixed this issue with the following patch-package patch.

patches/next-auth+4.22.1.patch

diff --git a/node_modules/next-auth/next/index.js b/node_modules/next-auth/next/index.js
index c592ca5..fc9f2e9 100644
--- a/node_modules/next-auth/next/index.js
+++ b/node_modules/next-auth/next/index.js
@@ -87,6 +87,7 @@ async function NextAuthRouteHandler(req, context, options) {
     return new Response(JSON.stringify({
       url: redirect
     }), {
+      status: internalResponse.status,
       headers: response.headers
     });
   }

You may also need to clear the .next folder after installing the patch (rm -rf .next)

Hey, Have you found a fix yet ? I’m running the same issue, I think I’m going insane

+1 same issue. I’m completely regretting of choosing nextauth as my auth library. It’s giving me headache after headache

+1 same issue. I’m completely regretting of choosing nextauth as my auth library. It’s giving me headache after headache

Check lucia auth for alternative or just use clerk.

Been having this problem for few weeks, guess ill just wait the official fix.

I have managed to do a workaround by adding throw new Error(""+res.status); inside authorize function if(response.status !== 200) And then in my login page I have SignIn("credentials", {email: values.email, password: values.password, redirect: false}).then((response:SignInRresponse | undefined) => { if(response?.error !== null) { if(response?.error === "401") form.setError("password", {message:"Incorrect password"}); } console.log(response ; }); this works for me and doesn’t create empty session but throws an error on the form and doesn’t sign in. Hope it helps, can provide more code if needed.

I ran into the exact same issue. As far as I can tell, this is happening only under the app router.

I fixed this issue with the following patch-package patch.

patches/next-auth+4.22.1.patch

diff --git a/node_modules/next-auth/next/index.js b/node_modules/next-auth/next/index.js
index c592ca5..fc9f2e9 100644
--- a/node_modules/next-auth/next/index.js
+++ b/node_modules/next-auth/next/index.js
@@ -87,6 +87,7 @@ async function NextAuthRouteHandler(req, context, options) {
     return new Response(JSON.stringify({
       url: redirect
     }), {
+      status: internalResponse.status,
       headers: response.headers
     });
   }

@igordanchenko I did it, but won’t work

Looks the same as #7725