req.session.user удаляется, пока пользователь активен - PullRequest
0 голосов
/ 08 ноября 2018

Я установил тайм-аут сессии на 30 минут. Пока я все еще активен, req.session.user удаляется через 30 минут. Однако сессия все еще жива. Вот мой конфиг (я использую express-session и passport.js):

app.use(session({
    store: new RedisStore({client: <my client>, disableTTL: true}),
    secret: <some_secret>,
    resave: true,
    saveUninitialized: false,
    cookie: {maxAge: 1800000}
}));

app.use(passport.initialize());
app.use(passport.session());

// Are these serializer/deserializer needed?
passport.serializeUser((user, done) => {
    done(null, user);
});
passport.deserializeUser((user, done) => {
    done(null, user);
});

В логине:

router.post('/login', (req, res, next) => {
    passport.authenticate('ldapauth', {session: false}, (err, user, info) => {
        ...
        if (user) {
            req.session.user = {email: req.body.username};
        }
        next();
    })(req, res);
});

Код подтверждения выглядит следующим образом:

isLoggedIn() {
    if (req.session && req.session.user) {
        return true;
    }
    return false;
}

Я установил req.session.user для некоторого объекта после успешного входа в систему.

Итак, через 30 минут req.session.user удаляется, но req.session все еще там и продолжает увеличивать дату истечения, поскольку я все еще активно работаю над страницей.

Почему req.session.user удаляется через 30 минут? Я думал, что паспорт едет на сессии экспресс?

* ОБНОВЛЕНИЕ * Сначала я думал, что срок действия увеличивается, но это не так. Ранее я установил resave: false. Затем, когда я регистрирую сеанс, срок действия всегда один и тот же:

Session {
    cookie:
         { path: '/', _expires: <some date>.... }
    user:
         { email: <the one i set before>, sessionId: <some id> } }

Затем через 30 минут пользователь удаляется. Только в этот момент срок действия начинает увеличиваться.

Session {
    cookie:
         { path: '/', _expires: <some date>.... }

Затем я прочитал кое-что о touch методе, который вызывает экспресс-сеанс. В документации сказано, что если хранилище реализует этот метод touch, тогда можно установить resave: false. Итак, думая, что redis может не реализовывать этот метод, я попытался установить resave: true. Затем, когда я регистрирую сеанс, я заметил, что срок действия увеличивается, по сравнению с предыдущим, что он увеличивается только после удаления пользователя. Однако через 30 минут снова пользовательский ключ удаляется.

Затем с предложением нири я установил disableTTL: true. Снова произошло то же самое.

В redis я пытаюсь получить ключ. До истечения 30 минут, срок действия в Redis увеличивается:

127.0.0.1:6379> mget sess:<some id>

1) "{\" cookie \ ": {\" originalMaxAge \ ": 1800000, \" expires \ ": \" 2018-11-15T06: 04: 26.994Z \ ", \" httpOnly \ ": true , \ "path \": \ "/ \"}, \ "user \": {\ "email \": \ "test@email.com \", \ "sessionId \": \ "некоторый идентификатор сеанса \" }} "

Затем через 30 минут я посмотрел на redis, сеансовый ключ все еще там, но он прекратил увеличивать срок действия. Хотя req.session все еще увеличивает срок действия, но свойство пользователя удаляется.

1 Ответ

0 голосов
/ 15 ноября 2018

Почему файл req.session.user удаляется через 30 минут?

Поскольку параметр cookie для maxAge установлен на 1800000 мс, что составляет 30 минут. Таким образом, браузер (или любой используемый вами клиент) удалит cookie через 30 минут.

Сеанс - это некоторая информация, которую вы хотите сохранить при последующих запросах. Обычно сеанс имеет идентификатор (sessionID) и связанную полезную нагрузку. Когда вы делаете req.session = { ... }, промежуточное ПО express-session получает объект, генерирует ID и сохраняет его в указанном вами store. (RedisStore в вашем случае). Итак, теперь ваша «база данных» имеет отображение sessionID и payload.

Файлы cookie - это то, что после отправки с сервера они будут перенаправляться каждый раз на этот сервер (в этот домен) для каждого последующего запроса до истечения срока их действия. Обратите внимание, что после получения куки-файла клиент должен управлять им. Сгенерированный sessionID вместе с подписью отправляется клиенту в cookie.

После того, как cookie сохранен на вашем клиенте. Он будет отправлен со следующим запросом. Когда ваше промежуточное программное обеспечение express-session видит файл cookie, оно извлекает sessionID из файла cookie и пытается найти соответствующую полезную нагрузку в store (RedisStore в вашем случае). Полезная нагрузка затем устанавливается на req.session вместе с другой информацией.

Как только истечет время истечения, клиент удалит cookie. Таким образом, запрос от этого клиента не будет иметь cookie. Поскольку cookie там нет, express-session не сможет установить req.session, и вы можете подумать, что пользователь вышел из системы. Обратите внимание, что хранилище все еще содержит отображение sessionID, payload, которое будет удалено в соответствии с ttl config store.


Я думаю, что путаница возникла в первую очередь из-за поля session.cookie. session.cookie всегда будет там из-за промежуточного программного обеспечения express-session.

Если вы хотите увидеть фактические куки, полученные в запросе, попробуйте cookie-parser middleware.


Я прилагаю пример кода к повозке. Конечная точка set-cookie установит cookie, срок действия которых истекает через 20 секунд. Конечная точка get-cookie получит данные cookie и session.

Надеюсь, это поможет!

const express = require("express");
const session = require("express-session");
const cookieParser = require("cookie-parser");
const FileStore = require("session-file-store")(session);
const path = require("path");

const app = express();

app.use(express.json());

app.use(cookieParser());
app.use(
    session({
        secret: "top secret!",
        resave: false,
        rolling: true,
        saveUninitialized: false,
        cookie: {
            maxAge: 20 * 1000
        },
        name: "demo",
        store: new FileStore({
            path: path.join(__dirname, "../sessions"),
            retries: 1,
            fileExtension: ".json"
        })
    })
);

app.use("/set-cookie", (req, res) => {
    req.session.payload = { foo: "bar", timestamp: new Date().toISOString() };
    res.json({ message: "done" });
});

app.use("/get-cookie", (req, res) => {
    res.json({
        sessionID: req.sessionID,
        session: req.session,
        cookies: req.cookies,
        timestamp: new Date().toISOString()
    });
});

app.listen(3000, err => {
    if (err) {
        throw err;
    }
    console.log("demo app listening on port 3000");
});

UPDATE Исходя из комментариев, вы ищете вариант rolling. Как только вы установите rolling: true в express-session, сеанс будет обновляться для каждого запроса. И пользователь выйдет из системы после maxAge ИДЕАЛЬНОГО времени.

Я обновил код.

...