如何使用 mongo db 的下一个身份验证凭据提供程序创建一个简单的重置密码 我有这样的用户模式
const userSchema = new mongoose.Schema<UserSchemaType>(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
img: { type: String, required: true },
isAdmin: { type: Boolean, required: true, default: false },
},
{
timestamps: true,
}
);
我的下一个授权看起来像这样
providers: [
CredentialsProvider({
async authorize(credentials) {
await db.connect();
const user = await User.findOne({
email: credentials.email,
});
if (user && bcryptjs.compareSync(credentials.password, user.password)) {
return {
_id: user._id,
name: user.name,
email: user.email,
image: user.img,
isAdmin: user.isAdmin,
};
}
throw new Error('Invalid email or password');
},
}),
],
});
是否有一个简单的示例来实现下次身份验证重置密码
我不认为
next-auth
为此提供任何特殊功能。您必须实施一般流程。用户应该有 Forgot Password
按钮,然后您将请求发送到 next.js api 后端。 “pages/api/forgot.js”
import jwt from "jsonwebtoken";
handler.post(async (req, res) => {
try {
await db.connectDb();
const { email } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ message: "Email does not exist." });
}
// create token with jwt
const user_token =jwt.sign(user._id, process.env.RESET_TOKEN_SECRET, {
expiresIn: "1h",
});
// you should create "pages/reset/[token].js" dynamic page
const url = `${process.env.BASE_URL}/reset/${user_id}`;
// you need to implement sedning email maybe using `nodemailer`
// create this function for your case
sendEmail(email, url, "Reset your password.");
// you should disconnect the db here
res.json({
message: "An email has been sent to you to reset your password.",
});
} catch (error) {
res.status(500).json({ message: error.message });
}
});
“pages/reset/[token].js”页面您将有一个包含 2 个输入的表单。 “密码”和“确认密码”。用户单击重置按钮后,您将密码和解密的令牌(我们使用 user_id 创建了令牌)发送到另一个后端 api:“pages/api/reset.js”。该后端将获取
user_id
和密码,查询数据库并更改密码
handler.put(async (req, res) => {
try {
await db.connectDb();
const { user_id, password } = req.body;
const user = await User.findById(user_id);
if (!user) {
return res.status(400).json({ message: "Account does not exist." });
}
const hashedPassword = await bcrypt.hash(password, 12);
await user.updateOne({
password: hashedPassword,
});
res.status(200).json({ email: user.email });
// you should disconnect the db
} catch (error) {
res.status(500).json({ message: error.message });
}
});
来自文档 - https://next-auth.js.org/providers/credentials
为基于凭据的身份验证提供的功能是 故意限制以阻止使用密码,因为 与它们相关的固有安全风险以及额外的 与支持用户名和密码相关的复杂性。
如果您确实需要此功能,也许您可以使用电子邮件提供商并进行自定义。
这是一个人如何在register/route.ts中实现注册。
我认为有一个类似的方法,通过创建一个按钮,使用 PUT 请求而不是 POST 请求转到重置密码/route.ts。
祝你好运!
import { NextResponse } from "next/server";
import prisma from "@/prisma/prisma";
import { createUserSchema } from "@/lib/user-schema";
import { ZodError } from "zod";
import { hashPassword } from "../../../app/utils/passwordUtils";
export async function POST(req: Request) {
const { name, email, password } = createUserSchema.parse(await req.json());
const { hashString , saltString} = await hashPassword(password);
console.log("hello", {hashString, saltString})
try {
const user = await prisma.user.create({
data: {
name,
email: email.toLowerCase(),
password: hashString,
salt: saltString,
},
});
return NextResponse.json({
user: {
name: user.name,
email: user.email,
},
});
} catch (error: any) {
if (error instanceof ZodError) {
return NextResponse.json(
{
status: "error",
message: "Validation failed",
errors: error.errors,
},
{ status: 400 }
);
}
if (error.code === "P2002") {
return NextResponse.json(
{
status: "fail",
message: "user with that email already exists",
},
{ status: 409 }
);
}
return NextResponse.json(
{
status: "error",
message: error.message || "Internal Server Error",
},
{ status: 500 }
);
}
}