Passport Session序列化失败(Bad Gateway)及用户认证相关问题求助
问题分析与解决方案
看起来你遇到了几个关联的问题,都是Passport和session配置、模型使用的细节错误导致的,咱们一步步来修复:
1. "Failed to serialize session" 与 req.user 为 undefined 的核心原因
你的deserializeUser函数里调用了User.findById,但你的Mongoose模型实际命名为Tweet,这里找不到User对象,直接导致session反序列化失败,用户信息无法正确存储,自然req.user就会是undefined。
修复代码:
passport.deserializeUser(function(id, done) { // 把User改成你的实际模型名Tweet Tweet.findById(id, function(err, user) { done(err, user); }); });
另外,Passport-Local-Mongoose已经封装了序列化和反序列化的方法,你可以用更简洁不易出错的写法替代手动实现:
passport.serializeUser(Tweet.serializeUser()); passport.deserializeUser(Tweet.deserializeUser());
2. 注册请求返回Bad Request的问题
路由拼写错误
你的EJS表单里写的是action="/regsiter",后端路由也是app.post("/regsiter")——注意单词拼写错误!正确的单词是register(少了字母t),前后端路由不匹配就会返回400 Bad Request。
修复EJS表单:
<form action="/register" method="post" class="login">
修复后端路由:
app.post("/register", bodyParser.urlencoded({extended: true}), (req, res)=>{ console.log(req.body.email); Tweet.register({username: req.body.email}, req.body.password, (err, user)=>{ if(err){ console.log(err); res.redirect("/register"); // 这里也要同步修改拼写 }else{ passport.authenticate("local")(req, res, function(){ // 注册成功后建议跳转到主页,而不是回到注册页 res.redirect("/"); }) } }) });
多余的逻辑判断
你原来代码里的if(user)判断是多余的——Tweet.register成功后一定会返回用户对象,去掉这个判断可以简化逻辑。
3. Tweet.find() 中 req.user.id 为 undefined 的问题
这个问题是前面session反序列化失败的连锁反应,修复完第一个问题后,req.user就能正确获取到用户信息,req.user.id也会正常可用。建议在路由里先判断用户是否已认证,避免未登录时的错误:
app.post("/tweets", (req, res)=>{ const Gottweets= req.body.tweet; console.log(Gottweets); console.log(req.user); // 先验证用户是否已登录 if(req.isAuthenticated()){ Tweet.findById(req.user.id, (err, foundUser)=>{ if(err){ console.log(err); res.redirect("/tweets"); }else{ if(foundUser){ foundUser.tweets = Gottweets; foundUser.save(()=>{ res.redirect("/"); }) } } }) } else { // 用户未登录时跳转到注册/登录页 res.redirect("/register"); } });
额外优化建议:模型命名
你的模型叫Tweet但实际存储的是用户信息(用户名、密码、用户的推文),这很容易混淆,建议改成User提升代码可读性:
// 重命名schema和模型 const userSchema = new mongoose.Schema({ username: String, password: String, tweets: String }); userSchema.plugin(passportLocalMongoose); const User = new mongoose.model("User", userSchema); // 同步修改Passport配置 passport.use(new LocalStrategy(User.authenticate())); passport.serializeUser(User.serializeUser()); passport.deserializeUser(User.deserializeUser());
内容的提问来源于stack exchange,提问作者Hassan Shah
相关产品推荐
相关产品推荐

