问题描述
无论我如何更改用户登录名,都会一直重定向到失败而不是成功。我不知道是我遗漏了什么,还是我做错了什么。我试图阅读护照文件,但我发现它很混乱。如果您需要查看其余代码,这是我的 github 链接。节点文件在app.js 和passport-config.js 中。网站的注册部分正在运行。 https://github.com/gego144/to-do-list-website/tree/main
const customFields = {
usernameField: 'email',passwordField: 'password'
}
const verifyCallback = (username,password,done) => {
user_exists = userName_Checker(username),function (err,user) {
if (err) { return done(err); }
if (userName_Checker(username) == false) {
console.log('wrong user');
return done(null,false,{ message: 'Incorrect username.' });
}
if (password_finder(username,password)) {
console.log('wrong pass');
return done(null,{ message: 'Incorrect password.' });
}
console.log('wtf');
return done(null,user);
};
;
}
const strategy = new LocalStrategy(customFields,verifyCallback);
passport.use(strategy);
passport.serializeUser(function(user,done) {
done(null,user);
});
passport.deserializeUser(function(id,done) {
User.findById(id,function(err,user) {
done(err,user);
});
});
// function that checks to see if the users email is in the database
function userName_Checker(email_name){
var sql = "select * from info where email = ?";
var user_email = [[email_name]];
db.query(sql,[user_email],result){
if (err) throw err;
var not_unique = result.length;
if(not_unique == 0){
return false;
}
else{
return true;
}
}
)}
// function that checks to see if the password in the database matches with the email
function password_finder(email_name,pass){
var sql = "SELECT password FROM info WHERE email = ?";
var user_email = [[email_name]];
db.query(sql,result){
if (err) throw err;
bcrypt.compare(result,pass,res){
if(err){ throw err};
if(res){
return true;
}
else{
return false;
}
})
}
)}
app.post('/login',passport.authenticate('local',{
successRedirect: '/',failureRedirect:'/index.html',failureFlash: true
}))
编辑 1。 我只想提一下,您在 verify Callback 中看到的 console.logs 出于某种原因也没有记录任何内容。
解决方法
问题可能出在序列化逻辑上。
在 const itemsHTML = tableItems.map(item =>
Array(item.quantity).fill("<option value='" + item.itemid + "'>" + item.itemName + "</option>").join('')
).join('');
$("#sbOne").append(itemsHTML)
中,您传递的是整个 passport.serializeUser
对象,但是在反序列化时您传递的是 user
虽然我没有使用 SQL,但逻辑应该是相似的。
所以代码应该是这样的:
id
// Session
// Pass in user id => keep the session data small
passport.serializeUser((id,done) => {
done(null,id);
});
// Deserialize when needed by querying the DB for full user details
passport.deserializeUser(async (id,done) => {
try {
const user = await User_DB.findById(id);
done(null,user);
} catch (err) {
console.error(`Error Deserializing User: ${id}: ${err}`);
}
});
这些护照选项似乎经常出现故障或表现出奇怪的行为,因此我建议您像在我的控制器中一样处理重定向逻辑。
// Export the passport module
module.exports = (passport) => {
passport.use(new LocalStrategy({ usernameField: 'email',},async (email,password,done) => {
try {
// Lookup the user
const userData = await User_DB.findOne({ email: email,{
password: 1,}); // Return the password hash only instead of the whole user object
// If the user does not exist
if (!userData) {
return done(null,false);
}
// Hash the password and compare it to the hash in the database
const passMatch = await bcrypt.compare(password,userData.password);
// If the password hash does not match
if (!passMatch) {
return done(null,false);
}
// Otherwise return the user id
return done(null,userData.id);
} catch (err) {
passLog.error(`Login Error: ${err}`);
}
}));
};
登录控制器逻辑: (我省略了此处用于会话存储的代码并进行了一些修改,但此代码应该可以满足您的需求)
{ successRedirect: '/good',failureRedirect: '/bad' }
实际路线:
const login = (req,res,next) => {
//Using passport-local
passport.authenticate('local',async (err,user) => {
//If user object does not exist => login failed
if (!user) { return res.redirect('/unauthorized'); }
//If all good,log the dude in
req.logIn(user,(err) => {
if (err) { return res.status(401).json({ msg: 'Login Error',}); }
// Send response to the frontend
return res.redirect('/good');
});
});
})(req,next);
};