我有一个示例节点应用程序,我试图在其中使用passport js注册登录和注销用户。我可以成功地登录和注册用户,但当我试图在我的终端注销用户时,我只得到我的反序列化函数的console.log,它不会影响我浏览器中的cookie,也不会注销用户,因为我可以在调用注销函数后检索req.user。下面是我的passport和express设置、序列化和反序列化函数,以及我的注销、注册和登录函数:
//middleware
app.use(session({
secret: "secret",
resave: true,
saveUninitialized: true,
cookie: {maxAge:60*60*1000}//1hour
}));
app.use(express.urlencoded({
extended: false
}));
app.use(express.json());
app.use(cors({
origin: "http://localhost:3000",
credentials: true,
}));
app.use(cookieParser("secret"));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, cb) => {
console.log("serializing user");
cb(null, user.id);
});
passport.deserializeUser((id, cb) => {
User.findById(id).then((err, user) => {
if(err) throw err;
console.log("id: " + id);
console.log("userid: " + user);
const userInformation = {
username: user.email,
};
cb(err, user);
}).catch((err) => {console.error(err)});
});
passport.use(
new localStrategy(async (username, password, done) => {
try{
const user = await User.findOne({username: username});
if(!user) {
console.log("no user");
return done(null, false);
}
bcrypt.compare(password, user.password, (err, result) => {
if(err) throw err;
if(result === true) {
return done(null, user);
} else {
return done(null, false);
}
});
} catch(err){
console.log("err inside localStrategy: " + err);
throw err;
}
})
);
app.post("/login", (req, res) => {
console.log("inside login");
passport.authenticate("local", (err, user, info) => {
console.log("inside authenticate, user: " + user);
if(err) {
console.log("err: " + err);
throw err;
}
if(!user) {
console.log("No user");
res.status(400);
res.send("No user exists");
}
else {
console.log("inside else");
req.logIn(user, (err) => {
if(err) throw err;
console.log("req.user: " + req.user);
console.log("successfully authenticated");
res.status(200).json({message: "successfully authenticated here"});
});
}
})(req, res);
});
app.post("/register", async (req, res) => {
try {
console.log("username: " + req.body.username);
const existingUser = await User.findOne({username: req.body.username});
if(existingUser) {
console.log("duplicate user");
return res.status(400).json({message: "User already exists"});
}
console.log("password to be hashed: " + req.body.password);
//hash password
const newUser = new User({
username: req.body.username,
password: req.body.password
});
bcrypt.genSalt(10, (err,salt)=>
bcrypt.hash(newUser.password, salt,
(err, hash) =>{
if(err) throw err;
newUser.password = hash;
newUser.save()
.then((value)=> {
console.log("value: " + value);
console.log("registered: " + newUser.username);
return res.status(200).json({message: "User successfully registered"});
})
.catch(err => console.log(err));
}
)
);
}
catch (err) {
console.log("error registering: " + err);
res.status(500).json({message: "Internal srever error"});
}
});
app.get("/logout", function(req, res){
req.logout();
req.session.destroy(function(err){
if(err){
console.log("error: " + err);
res.status(500).json({message: "Error destroying session"});
} else {
console.log("destroying session");
res.clearCookie('mcookie');
res.status(200).json({message: "Logged out successfully"});
}
});
});
1条答案
按热度按时间uinbv5nw1#
问题出在
passport.deserializeUser
函数中。OP在他们的描述中说,它记录
deserializeUser
函数,没有任何变化。因此,程序的控制流似乎永远不会超出deserializeUser
函数。如果我们查看浏览器的网络控制台,它会记录500 Internal Server error
。此外,OP还说,
req.logout
函数没有回调,永远不会在其端给出错误。而且它应该会失败,因为这个函数,截至目前(版本0.6.0),requires a callback。这也引起了一些人的注意。解决方案
阅读代码,似乎错误出现在
findById
函数的then
部分:看来你已经交换了那些论点。所以解决方案就是简单地交换这些参数。
所以现在程序应该运行良好,它应该调用你的
req.logout
函数。这应该会给予错误,因为你没有向函数传递回调。希望这有帮助!问你是否需要澄清。