#node.js #express #session #next.js #openlitespeed
#node.js #экспресс #сеанс #next.js #openlitespeed
Вопрос:
Привет сообществу Stackoverflow.
Итак, я сталкиваюсь с очень странной проблемой при размещении моего nextjs на базе Express с openlitespeed. Все отлично работает в рабочей среде, за исключением одной вещи — аутентификации сеансов. Пользователь правильно сохраняется в файлах cookie, и это работает, если вы не простаиваете более минуты на странице, на которой находитесь, но если вы простаиваете более минуты, то запрос больше не аутентифицируется, даже если файл cookie все еще там.
Я использую redis для своего хранилища файлов cookie, и все работает в локальном тестировании, где openlitespeed отсутствует. Аутентификация, которую я использую, — 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}`)
})
})
Комментарии:
1. Просто любопытно, как вы настроили OpenLiteSpeed в качестве обратного прокси?
2. Привет, Эрик. Извините за поздний ответ. Честно говоря, я просто использовал настройки сообщества из linode и настроил его для своих нужд
Ответ №1:
Хорошо, я наконец понял это. Конфигурация для Openlitespeed была настроена так, чтобы он мог создавать столько httpd workers, сколько захочет. Поэтому, когда был создан новый и запросы перешли к нему, кажется, что аутентификация не сработала. Я исправил это, установив «Количество рабочих» равным 1 в разделе Конфигурация сервера -> Процесс сервера -> Количество рабочих.
Что касается моего server.js файл, который я использовал для настройки nextjs и 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}`);
});
});
Комментарии:
1. ПРИВЕТ @muggel, спасибо, что поделились. Я видел, что некоторые другие люди также хотят настроить NextJS на OLS, но не знают, как это сделать. Возможно ли, чтобы вы поделились некоторыми базовыми знаниями или шагами о том, как это сделать, и я помогу записать это в документе LiteSpeedtech.
2. Привет @Eric. Извините за поздний ответ, но я был бы рад помочь. Как уже упоминалось, я использовал linode stackscript для базовой настройки nodejs openlitespeed. Есть ли что-нибудь конкретное, что вы хотели бы, чтобы я объяснил или?
3. Я вижу, вы запускаете сервер с docs.litespeedtech.com/cloud/images/nodejs . Могу ли я узнать, готовы ли вы поделиться примером кода приложения NextJS и как вы размещаете его на сервере, чтобы он работал в деталях? тогда я могу помочь поделиться методом в документе.
4. Привет @Eric. Я начал с этого stackscript: cloud. linode.com/stackscripts/458633 . Это устанавливает nodejs openlitespeed. Что касается сервера, я использую express вместе с nextjs. РЕДАКТИРОВАТЬ: кажется, я не могу вставить server.js файл, который я использую здесь, но я отредактировал его в ответ, который я дал