Next Auth – signIn函数始终返回状态码200。

huangapple go评论72阅读模式
英文:

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 = () =&gt; {
    const router = useRouter();
    const [loginError, setLoginError] = useState();

    const handleLogin = async (e) =&gt; {
        e.preventDefault();

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

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

    return (
        &lt;div className={styles.login}&gt;
                &lt;form onSubmit={handleLogin} className={styles.form}&gt;
                    &lt;h2 className={styles.header}&gt;Login&lt;/h2&gt;
                    &lt;input
                        type=&quot;text&quot;
                        placeholder=&quot;Login&quot;
                        className={styles.input}
                    /&gt;
                    &lt;input
                        type=&quot;password&quot;
                        placeholder=&quot;Hasło&quot;
                        className={styles.input}
                    /&gt;
                    &lt;button className={styles.button}&gt;Log in&lt;/button&gt;
                &lt;/form&gt;
                {loginError &amp;&amp; &lt;div&gt;ERROR&lt;/div&gt;}
        &lt;/div&gt;
    );
};

export default Login;

Route:

export const authOptions = {
    providers: [
        CredentialsProvider({
            id: &quot;credentials&quot;,
            type: &quot;credentials&quot;,

            credentials: {
                login: {
                    label: &quot;login&quot;,
                    type: &quot;text&quot;,
                },
                password: { label: &quot;Password&quot;, type: &quot;password&quot; },
            },
            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(&quot;Database Error&quot;, { 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: &quot;/login&quot;,
    },
};

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(&#39;Invalid credentials&#39;);
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(&#39;Invalid credentials&#39;);
}
} catch (error) {
return new NextResponse(&quot;Database Error&quot;, { 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

huangapple
  • 本文由 发表于 2023年6月27日 21:17:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76565308.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定