英文:
Next Auth - the signIn function always returns a status of 200
问题
I am creating my own login page in Next Auth and I have encountered a problem. After submitting the form, I check if the data is correct. If it is, I send JWT and redirect to /dashboard - it works as I would like. However, if the login data is incorrect I would like to return an error to my login page. However, when I return return null, the response status is 200, as if there is no error. Only the error property changes.
Currently, I base the return on the error and display the error based on it:
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="Hasło"
                        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 };
However, is this a good approach? Is it possible to return {status: 401, ok: false}?
英文:
I am creating my own login page in Next Auth and I have encountered a problem. After submitting the form, I check if the data is correct. If it is, I send JWT and redirect to /dashboard - it works as I would like. However, if the login data is incorrect I would like to return an error to my login page. However, when I return return null, the response status is 200, as if there is no error. Only the error property changes.
Currently, I base the return on the error and display the error based on it:
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="Hasło"
                        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 };
However, is this a good approach? Is it possible to return {status: 401, ok: false}?
答案1
得分: 1
这是一个关于 NextAuth 的 bug,但有一个 解决方法。
英文:
It is a bug in NextAuth but there is a workaround.
答案2
得分: 0
在数据无效的情况下,您返回了null。 null !== Error。如果数据无效,您需要抛出错误。
类似这样的代码:
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 });
}
英文:
You are returning null in case the data is invalid. null !== Error. You need to throw error if the data is invalid.
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 });
}
答案3
得分: 0
我在我的应用程序根目录(在node_modules级别)创建了一个名为patches的新文件夹,其中我添加了一个名为next-auth+4.22.1.patch的文件,将其中提供的代码粘贴进去。但是,当我运行npx patch-package next-auth时,我得到以下响应:
> PS C:\Users\iktor\Desktop\system> npx patch-package next-auth
patch-package 7.0.0
Creating temporary folder
Installing next-auth@4.22.1 with npm
Diffing your files with clean files
⁉️  Not creating patch file for package 'next-auth'
⁉️  There don't appear to be any changes.
而且文件/node_modules/next-auth/next/index.js没有被更新。我安装了next-auth ^4.22.1 版本。
英文:
I created a new folder patches in the root directory of my application (at the node_modules level), in which I added a file named next-auth+4.22.1.patch, into which I pasted the code given in the workaround. However, when I run npx patch-package next-auth, I get a response:
> PS C:\Users\iktor\Desktop\system> npx patch-package next-auth
patch-package 7.0.0
Creating temporary folder
Installing next-auth@4.22.1 with npm
Diffing your files with clean files
⁉️  Not creating patch file for package 'next-auth'
⁉️  There don't appear to be any changes.
And the file /node_modules/next-auth/next/index.js has not been updated.
I have the next-auth ^4.22.1 version installed
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论