You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用passport-local-mongoose开发注册登录页时触发MongooseError报错

问题描述

使用passport-local-mongoose开发注册/登录页面,注册后用户数据可正常存入MongoDB,但跳转至认证页面时触发以下错误:

MongooseError: Query.prototype.exec() no longer accepts a callback

问题代码
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const express = require('express')
const ejs = require("ejs");

const session = require('express-session');
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

const app = express()

app.use(bodyParser.urlencoded({ extended: true }))
app.set('view engine', 'ejs');
app.use(express.static("public"));

app.use(session({
  secret:'the s key',
  resave:false,
  saveUninitialized:false
}));

app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://0.0.0.0:27017/userDB", {useNewUrlParser: true});

const userSchema = new mongoose.Schema({
  username:String,
  password:String,
  tbd:String
});

//hash and salt psw and save users to db
userSchema.plugin(passportLocalMongoose);

const User = mongoose.model('User', userSchema);

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.get('/test', function(req,res){
  res.render('test');
});

app.get('/login', function(req,res){
  res.render('login');
});

app.get('/register',function(req,res){
  res.render('register');
});

app.get('/',function(req,res){
  res.redirect('login');
});

app.get("/mainpage",function(req,res){
  if(req.isAuthenticated()){
    console.log(req.isAuthenticated());
    res.render('/mainpage');
  }else{
    console.log(req.isAuthenticated());
    res.redirect('login');
  }
});

app.get('/logout',function(req,res){
  req.logout();
  res.redirct('/login')
})

app.post('/login',function(req,res){
  const user = new User({
    username:req.body.username,
    password:req.body.psw
  });

  req.login(user,function(err){
    if (err) {
      console.log(err);
    }else{
      passort.authenticate("local")(req, res, function(){
        res.redirct("/mainpage")
      })
    }

  });
});

app.post("/register", function(req, res){
  User.register({username: req.body.username}, req.body.password, function(err, user){
    if (err) {
      console.log(err);
      res.redirect("/register");
    } else {
        passport.authenticate('local').then(()=> {
        res.redirect("/mainpage");
    })
      }
  });

});

app.listen(3000, function() {
  console.log("Server started on port 3000");
});
解决方案

核心原因

错误源于Mongoose版本兼容性问题:当前使用的Mongoose是v6+版本,该版本已移除Query.prototype.exec()的回调参数支持,仅返回Promise;而旧版本的passport-local-mongoose仍在使用回调式exec(),导致冲突。此外代码中存在拼写错误,也会阻碍功能正常运行。

修复步骤

  1. 升级passport-local-mongoose
    安装适配Mongoose v6+的最新版本:

    npm update passport-local-mongoose
    
  2. 修正代码拼写错误

    • 将passort.authenticate改为passport.authenticate(登录路由中)
    • 将所有res.redirct改为res.redirect(登出、登录、注册路由中)
  3. 修正认证逻辑写法
    注册路由中passport.authenticate的用法错误,需改用标准中间件写法;同时建议用async-await优化异步逻辑,避免回调嵌套。

修复后的完整代码

const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const express = require('express')
const ejs = require("ejs");

const session = require('express-session');
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

const app = express()

app.use(bodyParser.urlencoded({ extended: true }))
app.set('view engine', 'ejs');
app.use(express.static("public"));

app.use(session({
  secret:'the s key',
  resave:false,
  saveUninitialized:false
}));

app.use(passport.initialize());
app.use(passport.session());

// 添加MongoDB连接错误处理
mongoose.connect("mongodb://0.0.0.0:27017/userDB", {useNewUrlParser: true, useUnifiedTopology: true})
  .then(() => console.log("Connected to MongoDB"))
  .catch(err => console.log(err));

const userSchema = new mongoose.Schema({
  username:String,
  password:String,
  tbd:String
});

userSchema.plugin(passportLocalMongoose);

const User = mongoose.model('User', userSchema);

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.get('/test', function(req,res){
  res.render('test');
});

app.get('/login', function(req,res){
  res.render('login');
});

app.get('/register',function(req,res){
  res.render('register');
});

app.get('/',function(req,res){
  res.redirect('login');
});

app.get("/mainpage",function(req,res){
  if(req.isAuthenticated()){
    console.log(req.isAuthenticated());
    // 修正:res.render参数为模板文件名,不需要加/
    res.render('mainpage');
  }else{
    console.log(req.isAuthenticated());
    res.redirect('login');
  }
});

app.get('/logout', function(req, res) {
  // 修正:req.logout需传入回调处理错误
  req.logout(function(err) {
    if (err) { return console.log(err); }
    res.redirect('/login');
  });
});

app.post('/login', function(req, res) {
  const user = new User({
    username: req.body.username,
    password: req.body.psw
  });

  req.login(user, function(err) {
    if (err) {
      console.log(err);
      return res.redirect('/login');
    }
    passport.authenticate("local")(req, res, function() {
      res.redirect("/mainpage");
    });
  });
});

app.post("/register", async function(req, res) {
  try {
    const user = await User.register({ username: req.body.username }, req.body.password);
    passport.authenticate('local')(req, res, function() {
      res.redirect("/mainpage");
    });
  } catch (err) {
    console.log(err);
    res.redirect("/register");
  }
});

app.listen(3000, function() {
  console.log("Server started on port 3000");
});

内容的提问来源于stack exchange,提问作者Swnoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 12:51:36