Простая аутентификация с проблемой Passport-Local и deSerializeUser - PullRequest
0 голосов
/ 12 января 2019

После прочтения отличного описания здесь о том, как десериализовать и сериализовать работу пользователя в потоке паспорта

Понимание паспорта сериализации десериализации

Меня беспокоит влияние на производительность вызова deSerializeUser при каждом запросе. Во всех примерах, которые я видел (см. Ниже), функция deserializeUser вызывает то, что похоже на базу данных User.findById, для выполнения этой работы. Предполагая, что вы не используете cdn для всех своих активов, это означает, что на каждую страницу загружается много вызовов базы данных.

Мои вопросы, я как-то неправильно понимаю вариант использования? Возможно ли, что при каждом запросе к серверу для данной веб-страницы рекомендуется выполнять вызов типа базы данных?

Если ответ «да», я предполагаю, что единственный способ исправить это - кэшировать учетные данные пользователя, но с точки зрения безопасности, я действительно ненавижу кэшировать учетные данные в целом.

Мысли

// used to serialize the user for the session
passport.serializeUser(function(user, done) {
    done(null, user.id); 
   // where is this user.id going? Are we supposed to access this anywhere?
});

// used to deserialize the user
  passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
      done(err, user);
    });
});

1 Ответ

0 голосов
/ 12 января 2019

В общем, да, вы хотите сохранить состояние / сеанс входа пользователя в базу данных и извлекать / обновлять его при каждом входящем запросе, так как он намного более отказоустойчив.

Предположим, что у вас нет базы данных, и вы храните сеанс на своем веб-сервере / сервере приложений, и может быть много таких серверов, обслуживающих один и тот же веб-сайт / приложение для обработки нагрузки. Если происходит сбой одного из ваших серверов, все ваши данные сеанса для всех пользователей, которые обслуживались этим сервером, будут потеряны (при таком подходе возникает еще одна сложность - вам нужно убедиться, что один пользователь обслуживается одним и тем же сервером веб / приложений). время, в течение которого его / ее сеанс хранится на этом сервере - так что вам нужно каким-то образом обрабатывать сходство сеансов / липкие сеансы на вашем балансировщике нагрузки, что обычно является болью, даже невозможным в некоторых случаях)

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

Вы можете кэшировать данные, скажем, с помощью Redis (или memcached), но тогда вам нужно убедиться, что кеш работает не на том же сервере, что и ваше приложение / веб, потому что вы столкнетесь с той же проблемой. (Redis, вероятно, является лучшим решением здесь, так как вы можете сделать его снимок и быстро восстановить его данные, если узел, на котором он работает, выходит из строя, вы не можете сделать это с memcached, по крайней мере, не напрямую)

Как правило, вы хотите хранить данные такого типа в БД, которая может хорошо обрабатывать этот тип трафика (например, Mongo, DynamoDB, Redis), а не в реляционной базе данных.

Что касается CND, в общем случае он не будет разгружать большую часть трафика из вашей БД (хранилища сеансов), поскольку вы, вероятно, не хотите предоставлять кэшированный статический контент только всем. Таким образом, вам все еще нужна какая-то проверка, для которой вам нужно сделать запрос к вашему серверу приложений, который все еще будет запрашивать БД, чтобы проверить, одобрен ли пользователь для запроса этого статического содержимого, создать какой-то подписанный URL, отправить его по адресу клиент и только после этого пользователь может получить доступ к защищенному контенту из CDN (но вы можете повторно использовать этот подписанный URL-адрес, если настроен таким образом, поэтому он может немного помочь).

...