Как сохранить подключенных пользователей с паспортом при перезагрузке сервера? - PullRequest
0 голосов
/ 20 мая 2018

Я играю с passport-local.Его использование очень простое, однако способ, которым паспорт устанавливает связь между cookie-session-id и подключенным пользователем, все еще остается для меня загадкой.

Я хотел бы сохранить в базе данных подключенные сеансы, чтобы:

  • Знать подключенных пользователей
  • Обнаружение изменений IP (из соображений безопасности)
  • Автоматическое отключение пользователей, которых давно не видели
  • Изменение номера сеанса для каждого запроса (по соображениям безопасности)
  • Сохранение подключения пользователей при перезагрузке сервера (полезно для отладки иобновление сервера)

Из этого нерабочего фрагмента ниже видно, что у меня есть две коллекции:

  • Одна для хранения зарегистрированных пользователей
  • Однадля хранения подключенных пользователей

Вот фрагмент:

import passport from 'passport'
import LocalStrategy from 'passport-local'

import mongoose from 'mongoose'

var UserSchema = new mongoose.Schema({
  username: String,    
  password: String
})

var Sessions = new mongoose.Schema({
  session: String, // Sessions of connected users 
  username: { type: Schema.Types.ObjectId, ref: 'User' },
  ip: String, // IP of the connected user 
  lastSeen: Date, // When the user made his last request 
})

var User = mongoose.model('UserSchema')

Как мне приступить к заполнению таблицы сеансов passport?

1 Ответ

0 голосов
/ 20 мая 2018

Ну, я думаю, что понял, и я должен быть в состоянии ответить на свой вопрос.

Паспорт не виновен

Паспорт не несет ответственности за постоянство, но express.session есть.Passport добавляет оболочку в middleware для перехвата HTTP-запросов и заполнения запроса такими методами и атрибутами, как LogOut или username.

По умолчанию express.session сохраняет данные в памяти, поэтому эти данные уничтожаются при остановке сервера.Паспорт хранит только одно поле в сеансе:

{ passport: { user: 'user-id' }}

Теперь мы реабилитировали Паспорт, мы можем сосредоточиться на сессиях.

Сеансы

Сеанс Express автоматически создает файл cookie с подписанным sid из секретного:

app.use (express.session ({
secret:'keyboard cat'})

Этот sid является идентификатором файла cookie и используется express.session для связи данных сеанса (хранящихся только на сервере) с запросом, сделанным клиентом.

Постоянный сеанс

Чтобы достичь того, что вы хотите сделать (... что я хотел бы сделать), вы должны сделать сеанс постоянным. Если вы используете MongoDB, вы можете использовать connect-mongo которые хранят данные сеанса в коллекции Mongo:

const MongoStore = require('connect-mongo')(express.session);

var app = express ();

app.configure(function() {
  app.use(express.session({     
    secret: 'keyboard cat', 
    rolling: true,
    store: new MongoStore({ url: 'mongodb://localhost/db', stringify: false })
  }));
  //...
}

Когда вы запускаете свой сервер и кто-то делает запрос, он добавляетвход в коллекцию БД:

{ 
    "_id" : "AcBXmfIXvz_y2Jp4nw1zfJvZTVPsCq7D", 
    "session" : {
        "cookie" : {
            "originalMaxAge" : null, 
            "expires" : null, 
            "secure" : null, 
            "httpOnly" : true, 
            "domain" : null, 
            "path" : "/"
        }, 
        "passport" : {
            "user" : NumberInt(1)
        }
    }, 
    "expires" : ISODate("2018-06-03T18:10:54.237+0000")
}

Вы можете видеть, что в Passport хранится только идентификатор пользователя, как объяснено.

В итоге

Знайте подключенных пользователей

Теперь у вас есть эта информация в MongoDB. Однако, когда пользователь отключается, tСеанс данных останется в базе данных.Вы можете использовать режим совместимости:

app.use(session({
    store: new MongoStore({
      url: 'mongodb://localhost/test-app',
      autoRemove: 'interval',
      autoRemoveInterval: 10 // In minutes. Default
    })
}));

Для автоматического удаления истекшего сеанса из базы данных.

Обнаружение изменений IP (по соображениям безопасности)

Вы должны сохранить эту информацию в сеансе с помощью:

req.session.ip = (req.headers['x-forwarded-for'] ||
     req.connection.remoteAddress ||
     req.socket.remoteAddress ||
     req.connection.socket.remoteAddress).split(",")[0];

Автоотключить пользователей, которых давно не видели

Вы должны реализовать это вручную.Вы можете использовать event из MongoStore, например, touch, срабатывающий при касании сеанса.

Изменение номера сеанса для каждого запроса (по соображениям безопасности)

Это более сложно, и у меня пока нет ответа.Изменение файла cookie sid между подключениями означает создание нового идентификатора сеанса и обновление MongoDB.У меня пока нет работающего решения.

Держите пользователей подключенными при перезагрузке сервера (полезно для отладки и обновления сервера)

Ну, это работает благодаряconnect-mongo

...