You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

集成Google认证的Node.js网站中,express-session使用MongoStore存储Session时出现TypeError: MongoStore is not a Constructor错误求助

解决 TypeError: MongoStore is not a constructor 错误

这个错误的核心问题在于你对connect-mongo的导入方式有误,再加上新版本库的API变化,导致无法正确实例化MongoStore。下面一步步帮你排查解决:

问题根源分析

  1. 语法错误的导入语句:你代码里的这一行是完全无效的:
    const MongoStore = require('connect-mongo');(session);
    
    分号把(session)变成了独立的表达式,既没有正确传入session参数,也破坏了变量赋值逻辑。
  2. connect-mongo版本的API变更:如果你的connect-mongo是v4及以上版本,它的导出方式和旧版本完全不同——不再需要手动传入session对象,而是通过create()方法来生成store实例。

分步解决方案

1. 修正导入语句

根据你安装的connect-mongo版本,选择对应的导入方式:

  • v4及以上版本(推荐,旧版本已停止维护)
    // 方式1:使用default导出
    const MongoStore = require('connect-mongo').default;
    // 方式2:解构语法
    const { default: MongoStore } = require('connect-mongo');
    
  • v3及以下版本
    要把session作为参数紧跟在require调用后(注意不要加分号):
    const MongoStore = require('connect-mongo')(session);
    

2. 调整Session Store配置

不同版本的配置写法略有区别:

  • v4及以上版本
    推荐使用MongoStore.create()方法来生成实例,支持直接传入MongoDB连接字符串或已有的mongoose连接:
    app.use(
      session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: false,
        store: MongoStore.create({
          // 二选一:用环境变量里的连接字符串
          // mongoUrl: process.env.MONGO_URI,
          // 或者用已有的mongoose连接
          mongooseConnection: mongoose.connection
        }),
      })
    );
    
  • v3及以下版本
    可以继续使用new MongoStore()的写法,只要导入正确即可:
    app.use(
      session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: false,
        store: new MongoStore({ mongooseConnection: mongoose.connection }),
      })
    );
    

3. 修复代码里的其他小问题

你的代码里还有两个容易忽略的错误:

  • 日志中间件的写法错误:app.use('morgan'('dev'));应该改为app.use(morgan('dev'));(多了一对引号)
  • 静态文件夹使用了path模块但未导入:需要在顶部添加const path = require('path');

修正后的完整代码片段(以v4版本为例)

const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const morgan = require('morgan');
const exphbs = require('express-handlebars');
const methodOverride = require('method-override');
const passport = require('passport');
const session = require('express-session');
const MongoStore = require('connect-mongo').default;
const connectDB = require('./config/db');
const path = require('path'); // 新增path导入

//Load Config
dotenv.config({path: './config/config.env'});

//Passport Config
require('./config/passport')(passport);

connectDB();

const app = express();

//Logging
if(process.env.NODE_ENV === 'development') {
    app.use(morgan('dev')); // 修正日志中间件写法
}

//Handebars
app.engine('.hbs', exphbs({defaultLayout: 'main', extname: '.hbs'}));
app.set('view engine', '.hbs');

// Express Sessions
app.use(
    session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: false,
        store: MongoStore.create({
            mongooseConnection: mongoose.connection
        }),
    })
);

// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());

//Static folder
app.use(express.static(path.join(__dirname, 'public')));

//ROUTES
app.use('/', require('./routes/index'));
app.use('/auth', require('./routes/auth'));

const port = process.env.PORT || 3000
app.listen(port, () => console.log(`Server Running in ${process.env.NODE_ENV} mode on port ${port}`) );

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

火山引擎 最新活动