0

我正在创建一个 Next.js 网络应用程序......

在服务器文件夹内的 app.js 文件中,我有以下代码:

const express = require("express");
const next = require("next");

const expressValidator = require("express-validator");
const mongoose = require("mongoose");
const passport = require("passport");
const mongoSessionStore = require("connect-mongo");
const session = require("express-session");

/* Loads all variables from .env file to "process.env" */
// npm instsall dotenv
// require("dotenv").config();

require("./models/Listing");
require("./models/User");

const routes = require("./routes");

const dev = process.env.NODE_ENV !== "production";
const port = process.env.PORT || 3000;
const ROOT_URL = dev ? `http://localhost:${port}` : process.env.PRODUCTION_URL;
const app = next({ dev });
const handle = app.getRequestHandler();

const mongooseOptions = {
    useNewUrlParser: true,
    useCreateIndex: true,
    useFindAndModify: false,
    useUnifiedTopology: true
};

mongoose
    .connect(
        process.env.MONGODB_URI,
        mongooseOptions
    )
    .then(() => console.log("DB connected"));

mongoose.connection.on("error", err => {
    console.log(`DB connection error: ${err.message}`);
});

app.prepare().then(() => {
    const server = express();

    if(!dev) {
        /* Helmet helps secure our app by setting various HTTP headers */
        server.use(helmet());
        /* Compression gives us gzip compression */
        server.use(compression());
    }

    /* Body Parser built-in to Express as of version 4.16 */
    server.use(express.json());

    /* Express Validator will validate form data sent to the backend */
    // server.use(expressValidator());

    /* apply routes from the "routes" folder */
    server.use("/", routes);

    /* give all Next.js's requests to Next.js server */
    server.get("/_next/*", (req, res) => {
        handle(req, res);
    });

    server.get("/static/*", (req, res) => {
        handle(req, res);
    });

    const MongoStore = mongoSessionStore(session);
    const sessionConfig = {
        name: "next-connect.sid",
        // secret used for using signed cookies w/ the session
        secret: process.env.SESSION_SECRET,
        store: new MongoStore({
          mongooseConnection: mongoose.connection,
          ttl: 14 * 24 * 60 * 60 // save session for 14 days
        }),
        // forces the session to be saved back to the store
        resave: false,
        // don't save unmodified sessions
        saveUninitialized: false,
        cookie: {
          httpOnly: true,
          maxAge: 1000 * 60 * 60 * 24 * 14 // expires in 14 days
        }
      };

    if (!dev) {
    sessionConfig.cookie.secure = true; // serve secure cookies in production environment
    server.set("trust proxy", 1); // trust first proxy
    }

    /* Apply our session configuration to express-session */
    server.use(session(sessionConfig));

    /* Add passport middleware to set passport up */
    server.use(passport.initialize());
    server.use(passport.session());

    server.use((req, res, next) => {
        /* custom middleware to put our user data (from passport) on the req.user so we can access it as such anywhere in our app */
        res.locals.user = req.user || null;
        next();
    });


    server.get("*", (req, res) => {
        handle(req, res);
    });
        
    server.listen(port, err => {
        if (err) throw err;
        console.log(`Server listening on ${ROOT_URL}`);
    });
    
})

由于某种原因,当我运行上述代码时出现以下错误:

UnhandledPromiseRejectionWarning:TypeError:没有'new'就不能调用类构造函数MongoStore

似乎产生该错误的行似乎是:

const MongoStore = mongoSessionStore(session);

是什么原因造成的,我该如何解决?

4

4 回答 4

1

我的应用程序中遇到了同样的问题,因为我已将 connect-mongo 更新到最新版本(4.1)。我通过卸载现有的 connect-mongo 包并重新安装版本 3.1.2 解决了这个问题。您可以通过键入以下命令简单地安装版本:

npm install connect-mongo@3.1.2

或者您复制以下命令并在键入命令 npm install 后粘贴到您的 .json 文件中以更改版本:

"connect-mongo": "^3.1.2",
于 2021-08-14T05:04:35.960 回答
0

所以事实证明我正在复制的代码是使用 connect-mongo ^2.0.1 但我在 package.json 中的 connect-mongo 是 ^4.4.0

所以我需要将适合的代码从原始版本更改为新版本......这就是我最后得到的:

const sessionConfig = {
        name: "next-connect.sid",
        // secret used for using signed cookies w/ the session
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        store: MongoStore.create({
            mongoUrl: process.env.MONGODB_URI,
            mongooseConnection: mongoose.connection,
            ttl: 14 * 24 * 60 * 60 // save session for 14 days
        }),

        cookie: {
            httpOnly: true,
            maxAge: 1000 * 60 * 60 * 24 * 14 // expires in 14 days
        }
    }

    if (!dev) {
        sessionConfig.cookie.secure = true; // serve secure cookies in production environment
        server.set("trust proxy", 1); // trust first proxy
    }


    /* Apply our session configuration to express-session */
    server.use(session(sessionConfig));

到目前为止,我认为它工作正常......

于 2021-03-13T16:12:23.670 回答
0

可能是因为你使用的是connect-mongo@v4,你可以尝试使用npm i connect-mongo@3.2.0 --save来解决这个问题。

于 2021-03-20T10:12:16.857 回答
0

看起来 'mongoSessionStore' 是一个类构造函数。
一个类有关于如何为会话创建一个新对象的说明。这发生在构造函数中。

也许如果你只是在mongoSessionStore它起作用之前加上“新”这个词?
这样,Mongo 将为启动的 Session 创建一个对象。

于 2021-03-13T11:47:30.790 回答