【问题标题】:Openlitespeed Session Timeout after 1 min idle with Nextjs App使用 Nextjs 应用程序空闲 1 分钟后 Openlitespeed 会话超时
【发布时间】:2020-12-14 04:16:29
【问题描述】:

你好 Stackoverflow 社区。​​p>

因此,在使用 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}`)
  })
})

【问题讨论】:

  • 只是好奇您如何将 OpenLiteSpeed 设置为反向代理?
  • 嗨,埃里克。这么晚才回复很抱歉。老实说,我只是使用了 linode 的社区设置并根据我的需要对其进行了定制

标签: node.js express session next.js openlitespeed


【解决方案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}`);
  });
});

【讨论】:

  • 嗨@muggel,感谢分享。我看到其他一些人也想在 OLS 上设置 NextJS,但不知道如何。能不能给大家分享一些基础知识或者操作步骤,我会帮忙写在LiteSpeedtech文档上。
  • 你好@Eric。很抱歉回复晚了,但我很乐意提供帮助。如前所述,我使用 linode stackscript 来设置基本的 nodejs + openlitespeed 设置。有什么特别要我解释的吗?
  • 我明白了,你从 docs.litespeedtech.com/cloud/images/nodejs 启动服务器。我可以知道您是否愿意分享 NextJS 应用程序代码的示例,以及您如何将它放在服务器上以使其详细工作?那我可以帮忙分享一下文档上的方法。
  • 嗨@Eric。我从这个堆栈脚本开始:cloud.linode.com/stackscripts/458633。这安装了 nodejs + openlitespeed。至于服务器,我用的是 express 和 nextjs。编辑:我似乎无法插入我在这里使用的 server.js 文件,但我已将其编辑为我给出的答案
猜你喜欢
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 2013-03-31
  • 2013-04-17
  • 2013-06-18
  • 2021-12-28
  • 2013-06-15
  • 1970-01-01
相关资源
最近更新 更多