我正在制作一个简单的登录页面,使用 Node.js 作为后端内容,并使用护照进行身份验证。对我来说,我的所有代码看起来都不错并且看起来应该可以工作。我什至把它放进chatGPT也没有发现任何问题。无论登录页面的输入如何,即使它是正确的,我也会被重定向到 failureRedirect 页面。我知道密码和电子邮件是正确的,即使它们经过哈希处理和加盐处理,因为出于测试目的,我将它们设置为极其简单的 3 字符密码。我什至在我的数据库中看到了哈希密码。
我解决这个问题的方法是从用户那里获取提交的输入,对其进行加盐,然后对其进行散列,并将其存储到数据库中。然后,我使用本地护照策略通过将表单输入与用户输入进行比较来处理身份验证过程,如果匹配,则用户将被重定向到某个页面,如果不匹配,他们将被重定向到另一个页面,仅用于测试目的。我将在下面添加相关代码,以便您更好地了解我如何解决这个问题。
//my User model, exported correctly
const UserSchema = new Schema({
firstName: {type: String, required: true},
lastName: {type: String, required: true},
email: {type: String, required: true},
password: {type: String, required: true},
posts: {type: Schema.Types.ObjectId, ref: "Post"}
})
// password hashing code & user creation
asyncHandler(async (req, res, next) => {
try {
// Hash the password
const hashedPassword = await bcrypt.hash(req.body.password, 10);
// Check if user with the provided email already exists
const existingUser = await User.findOne({ email: req.body.email }).exec();
if (existingUser) {
return res.status(400).send('Email already exists. Please use a different one.');
}
// Create new user
const user = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: hashedPassword // Use the hashed password
});
await user.save();
// Redirect after successful registration
res.redirect("/");
} catch (err) {
next(err);
}
});
// snippet of my authentication
function configurePassport(passport) {
passport.use(new LocalStrategy( async (email, password, done) => {
try {
const user = await User.findOne({ email: email })
if (!user) {
//usernames do not match!
return done(null, false, { message: "Incorrect username" })
};
const match = await bcrypt.compare(password, user.password)
if (!match) {
// passwords do not match!
return done(null, false, { message: "Incorrect password" })
}
return done(null, user);
} catch(err) {
return done(err);
};
}));
}
h1= title
if user
h1 Welcome back #{user.firstName}
else
form(action="/", method="post")
input(type="email", name="email", placeholder="email")
input(type="password", name="password", placeholder="password")
button(type="submit") Log In
a(href="/register") Register Now
passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/register"
});
因此,我已经包含了用于架构初始化、用户创建和密码哈希、用户身份验证的代码,甚至包括使用带有 Passport.authenticate 代码的 pug 的登录表单。我几乎尝试了所有方法,但我不确定我哪里出错了。这是一个如此简单的应用程序,我觉得它必须是简单的东西。此外,configurePassword 函数已导入并在我的主应用程序中调用为
configurePassword(passport)
。
问题似乎是 LocalStrategy 策略期望每次输入的用户名和密码保持一致。我使用了电子邮件和密码的输入名称,这就是问题所在。要解决此问题,您只需在策略开始时实施命名选项即可。它看起来像这样。
function configurePassprt(passport) {
passport.use(new LocalStrategy({
usernameField: 'email', //changes the expected form input from username to email
passwordField: 'password
},
async (email, password, done) => {
try {
const user = await User.findOne({ email: email }); // Query database using 'email' field instead of username field
if (!user) {
// User with the provided email does not exist
return done(null, false, { message: "Incorrect email" });
}
const match = await bcrypt.compare(password, user.password);
if (!match) {
// Passwords do not match
return done(null, false, { message: "Incorrect password" });
}
// Authentication successful
return done(null, user);
} catch (err) {
// Error occurred during authentication process
return done(err);
}
}
));
}