0

你好 Stackoverflow 社区。

因此,在使用 openlitespeed 托管由 express 提供支持的 nextjs 时,我遇到了一个非常奇怪的问题。一切都在生产中运行良好,除了一件事 - 会话的身份验证。用户已正确保存在 cookie 中,如果您在当前页面上的空闲时间不超过一分钟,它就会起作用,但如果您空闲时间超过一分钟,那么即使 cookie 也不会再对请求进行身份验证还在那里。

我将 redis 用于我的 cookie 存储,并且在本地测试中一切正常,而 openlitespeed 不存在。我使用的身份验证是带 express-session 的 passportjs。大家有没有遇到过这个问题,如果有,你们是怎么解决的?我尝试禁用缓存模块,将所有超时设置为更高的值或禁用它们,使用不同的内存存储等等,但没有运气。这是 server.js 文件,但是,我认为它与代码本身无关,而是与 openlitespeed 的配置有关:

const express = require('express')
const next = require('next')
const passport = require('passport');
const redis = require('redis')
const session = require('express-session')
const {v4: uuidv4} = require('uuid');
const path = require('path');
const log = require('./logger')
let RedisStore = require('connect-redis')(session)
let redisClient = redis.createClient()

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

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

  //Json parsing
  server.use(express.json());
  server.use(express.urlencoded({extended: true}));


  if (dev){
    //Express session
    server.use(session({
      store: new RedisStore({ client: redisClient }),
      genid: function() {
        return uuidv4()},
      secret: uuidv4(),
      resave: false,
      saveUninitialized: false,
      cookie: {
        secure: false,
        maxAge: 86400000 
      }
  }))
  }
  else{
      //Express session
    server.use(session({
      store: new RedisStore({ client: redisClient }),
      genid: function() {
        return uuidv4()},
      secret: uuidv4(),
      proxy: true,
      resave: false,
      saveUninitialized: false,
      cookie: {
        secure: true,
        maxAge: 86400000
      }
  }))
  }


  //Passport auth
  server.use(passport.initialize());
  server.use(passport.session());

  //Import of the passport config 
const initializePassport = require('./passport-config');
initializePassport(passport);

//Login route
server.post('/login', passport.authenticate('login'), (req, res) => {
    res.send({message: 'Successful login', login: true})
});

const passportLogout = function (req, res, next) {
  req.logout()
  next()
}

//Logout route
server.get('/logout', passportLogout, (req, res) => {
    req.session.destroy();
    res.redirect('/login');
});

//Import registrerings route. Pga. brugen af route i stedet for app kan vi bruge denne middleware med en anden underside, hvis vi f.eks. ville gøre så admins også kunne lave brugere.
const registerRoute = require('./routes/register-user');
server.use('/register', registerRoute);

  //User routes hvor login er required. Rendering. Skal stå under called til initializepassport, ellers kan den ikke finde ud af at den er authenticated via passport, og auth.js returnerer dig derfor til login
  const usersRoutes =  require('./routes/user/user-routes');
  server.use(usersRoutes);

  //Admin routes til rendering
  const adminRoutes = require('./routes/admin/admin-routes');
  server.use(adminRoutes);

  const indexRoutes = require('./routes/index-routes');
  server.use(indexRoutes);


  server.all('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(port, (err) => {
    if (err) throw err
    log.logger.log({
      level: "info",
      message: `Server was started on ${port}`,
      additional: "properties",
      are: "passed along",
    });
    console.log(`> Ready on http://localhost:${port}`)
  })
})
4

1 回答 1

1

好吧,所以我终于想通了。Openlitespeed 的配置已设置,因此它可以创建任意数量的 httpd 工作人员。因此,当创建一个新的并且请求转到那个时,似乎身份验证没有坚持下去。我已通过在服务器配置 -> 服务器进程 -> 工作人员数量下将“工作人员数量”设置为 1 来解决此问题。

至于我用来设置 nextjs 和 openlitespeed 的 server.js 文件:

const express = require("express");
const next = require("next");
const passport = require("passport");
const redis = require("redis");
const session = require("express-session");
const { v4: uuidv4 } = require("uuid");
const path = require("path");
const log = require("./logger");
let RedisStore = require("connect-redis")(session);
let redisClient = redis.createClient({ auth_pass: process.env.DB_PASSWORD });

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

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

  //Json parsing
  server.use(express.json());
  server.use(express.urlencoded({ extended: true }));

  if (dev) {
    //Express session
    server.use(
      session({
        store: new RedisStore({ client: redisClient }),
        genid: function () {
          return uuidv4();
        },
        secret: uuidv4(),
        resave: false,
        saveUninitialized: false,
        cookie: {
          secure: false,
          maxAge: 86400000,
        },
      })
    );
  } else {
    //Express session
    server.use(
      session({
        store: new RedisStore({ client: redisClient }),
        genid: function () {
          return uuidv4();
        },
        secret: uuidv4(),
        proxy: true,
        resave: false,
        saveUninitialized: false,
        cookie: {
          secure: true,
          maxAge: 86400000,
        },
      })
    );
  }

  //Passport auth
  server.use(passport.initialize());
  server.use(passport.session());

  //Import of the passport config
  const initializePassport = require("./passport-config");
  initializePassport(passport);

  //Login route
  server.post("/login", passport.authenticate("login"), (req, res) => {
    res.send({ message: "Successful login", login: true });
  });

  const passportLogout = function (req, res, next) {
    req.logout();
    next();
  };

  //Logout route
  server.get("/logout", passportLogout, (req, res) => {
    req.session.destroy();
    res.redirect("/login");
  });

  //Import registrerings route. Pga. brugen af route i stedet for app kan vi bruge denne middleware med en anden underside, hvis vi f.eks. ville gøre så admins også kunne lave brugere.
  const registerRoute = require("./routes/register-user");
  server.use("/register", registerRoute);

  //User routes hvor login er required. Rendering. Skal stå under called til initializepassport, ellers kan den ikke finde ud af at den er authenticated via passport, og auth.js returnerer dig derfor til login
  const usersRoutes = require("./routes/user/user-routes");
  server.use(usersRoutes);

  //Admin routes til rendering
  const adminRoutes = require("./routes/admin/admin-routes");
  server.use(adminRoutes);

  const indexRoutes = require("./routes/index-routes");
  server.use(indexRoutes);

  server.all("*", (req, res) => {
    return handle(req, res);
  });

  server.listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on ${port}`);
  });
});
于 2020-08-26T07:09:43.760 回答