使用 Nextjs App 空闲 1 分钟后 Openlitespeed 会话超时 [英] Openlitespeed Session Timeout after 1 min idle with Nextjs App

查看:47
本文介绍了使用 Nextjs App 空闲 1 分钟后 Openlitespeed 会话超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好 Stackoverflow 社区.

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

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

const express = require('express')const next = require('next')const 护照 = 要求(‘护照’);const redis = require('redis')const session = require('express-session')const {v4: uuidv4} = require('uuid');const path = require('path');const log = require('./logger')让RedisStore = require('connect-redis')(session)让 redisClient = redis.createClient()const port = parseInt(process.env.PORT, 10) ||3000const dev = process.env.NODE_ENV !=='生产'const app = next({ dev })const handle = app.getRequestHandler()app.prepare().then(() => {const server = express()//json解析server.use(express.json());server.use(express.urlencoded({extended: true}));如果(开发){//快速会话服务器.使用(会话({商店:新的RedisStore({客户端:redisClient}),genid:函数(){返回 uuidv4()},秘密:uuidv4(),重新保存:假,保存未初始化:假,曲奇饼: {安全:假,最大年龄:86400000}}))}别的{//快速会话服务器.使用(会话({商店:新的RedisStore({客户端:redisClient}),genid:函数(){返回 uuidv4()},秘密:uuidv4(),代理:真的,重新保存:假,保存未初始化:假,曲奇饼: {安全:真实,最大年龄:86400000}}))}//护照认证server.use(passport.initialize());server.use(passport.session());//导入护照配置const initializePassport = require('./passport-config');初始化护照(护照);//登录路径server.post('/login',passport.authenticate('login'), (req, res) => {res.send({message: '登录成功', login: true})});constpassportLogout = 函数 (req, res, next) {req.logout()下一个()}//退出路由server.get('/logout',passportLogout, (req, res) => {req.session.destroy();res.redirect('/登录');});//导入注册路由.帕.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);//用户路由hvor login er required.渲染.Skal stå 下称为 til initializepassport,ellers kan den ikke finde ud af at den er 通过护照进行身份验证,og auth.js returnerer dig derfor til loginconst usersRoutes = require('./routes/user/user-routes');server.use(usersRoutes);//管理路由直到渲染const adminRoutes = require('./routes/admin/admin-routes');server.use(adminRoutes);const indexRoutes = require('./routes/index-routes');server.use(indexRoutes);server.all('*', (req, res) => {返回句柄(请求,资源)})server.listen(port, (err) => {如果(错误)抛出错误log.logger.log({级别:信息",消息:`服务器在 ${port}` 上启动,附加:属性",是:传递",});console.log(`> Ready on http://localhost:${port}`)})})

解决方案

好吧,我终于想通了.设置了 Openlitespeed 的配置,以便它可以创建任意数量的 httpd 工作线程.因此,当创建一个新的并且请求转到那个时,似乎认证没有坚持.我已经通过设置工人数量"来解决这个问题.到服务器配置下的 1 ->服务器进程 ->工人数量.

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

const express = require(express");const next = require("next");const 护照 = 要求(护照");const redis = require(redis");const session = require(express-session");const { v4: uuidv4 } = require(uuid");const path = require(路径");const log = require("./logger");让RedisStore = require(connect-redis")(session);让 redisClient = redis.createClient({ auth_pass: process.env.DB_PASSWORD });const port = parseInt(process.env.PORT, 10) ||3000;const dev = process.env.NODE_ENV !== 生产";const app = next({ dev });const handle = app.getRequestHandler();app.prepare().then(() => {const server = express();//json解析server.use(express.json());server.use(express.urlencoded({extended: true }));如果(开发){//快速会话服务器.使用(会议({商店:新的RedisStore({客户端:redisClient}),genid:函数(){返回 uuidv4();},秘密:uuidv4(),重新保存:假,保存未初始化:假,曲奇饼: {安全:假,最大年龄:86400000,},}));} 别的 {//快速会话服务器.使用(会议({商店:新的RedisStore({客户端:redisClient}),genid:函数(){返回 uuidv4();},秘密:uuidv4(),代理:真的,重新保存:假,保存未初始化:假,曲奇饼: {安全:真实,最大年龄:86400000,},}));}//护照认证server.use(passport.initialize());server.use(passport.session());//导入护照配置const initializePassport = require("./passport-config");初始化护照(护照);//登录路径server.post("/login",passport.authenticate("login"), (req, res) => {res.send({ message: "成功登录", login: true });});constpassportLogout = 函数 (req, res, next) {req.logout();下一个();};//退出路由server.get("/logout",passportLogout, (req, res) => {req.session.destroy();res.redirect(/登录");});//导入注册路由.帕.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);//用户路由hvor login er required.渲染.Skal stå 下称为 til initializepassport,ellers kan den ikke finde ud af at den er 通过护照进行身份验证,og auth.js returnerer dig derfor til loginconst usersRoutes = require("./routes/user/user-routes");server.use(usersRoutes);//管理路由直到渲染const adminRoutes = require("./routes/admin/admin-routes");server.use(adminRoutes);const indexRoutes = require("./routes/index-routes");server.use(indexRoutes);server.all(*", (req, res) => {返回句柄(req, res);});server.listen(port, (err) => {如果(错误)抛出错误;console.log(`> Ready on ${port}`);});});

Hello Stackoverflow Community.

So I am encountering a very weird problem when hosting my nextjs powered by express with openlitespeed. Everything works great in production, except one thing - the authentification of sessions. The user is saved in the cookies correctly and it works if you are not idle for more than a minute on the page you are on, but if you are idle for more than a minute, then the request is not authenticated anymore even though the cookie is still there.

I am using redis for my cookie store, and everything works in local testing, where openlitespeed is not present. The authentification I am using is passportjs with express-session. Have any of you encountered this problem, and if so, how did you solve it? I have tried disabling the cache module, set all timeouts to a higher value or disabling them, use different memorystores and more, but no luck. Here is the server.js file, however, I do not believe it has something to do with the code itself, but rather the config of 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}`)
  })
})

解决方案

All right, so I figured it out finally. The configuration for Openlitespeed was set, so that it could create as many httpd workers as it wants. Therefore, when a new was created and the requests went over to that one, it seems the authentification did not stick. I have fixed this by setting the "Number of Workers" to 1 under Server Configuration -> Server Process -> Number of Workers.

As for my server.js file I used to setup nextjs and 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({ 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}`);
  });
});

这篇关于使用 Nextjs App 空闲 1 分钟后 Openlitespeed 会话超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆