英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论