Я использую passportJS с выражением для аутентификации пользователя по локальной страtagsи. Я видел несколько статей, касающихся настройки паспорта и streamа выполнения. Хотя большинство вещей, связанных с паспортом, можно понять путем поиска, происходит сериализация и десериализация пользователя, что меня пугает.
Я понимаю, что он используется для сохранения пользовательской информации в сеансе для постоянного входа. Мой код для сериализации и десериализации
passport.serializeUser(function(user, done){ done(null, user.id); }); passport.deserializeUser(function(id, done){ User.findById(id, function(err, user){ done(err, user); }); });
Мой вопрос относительно этого
1) Кто вызывает и заполняет аргументы serializeUser и deserializeUser? И как он имеет доступ к пользовательскому объекту? Чтобы понять это, я добавил журнал как
passport.serializeUser(function(user, done){ console.log(arguments.callee.caller); done(null, user.id); });
И получил [Function: pass] в выходе. Может ли кто-нибудь объяснить это?
2) Я использую mongodb для хранения информации о пользователе. MongoDB имеет _id в качестве идентификатора по умолчанию для документа. Поэтому в идеале serializeUser и deserializeUser должны работать с user._id вместо user.id. Но он отлично работает с user.id, который недоступен в объекте User. Вот объект пользователя, напечатанный на консоли
{ _id: 5505f231b810dbd4098ac76a, __v: 0, google: {}, twitter: {}, facebook: {}, local: { password: '$2a$08$9NGd0xNu0JbWMZ07ufyFRu8guwy147k8IBl5cAC4Y8APOuxreNI32', email: 'xxxx@xxx.com' } }
Как это возможно?
3) Когда выполнение контрольного streamа done
один раз, done
метод?
После долгого времени поиска я нашел эту статью, которая объясняет stream аутентификации очень четко.
- Когда пользователь отправляет регистрационную форму, выполняется запрос POST для входа / входа, что приводит к выполнению паспорта. Подтверждение промежуточного программного обеспечения, которое мы установили.
- Поскольку аутентифицированное промежуточное ПО для этого маршрута настроено для обработки локальной страtagsи, паспорт будет ссылаться на нашу реализацию локальной страtagsи.
- Паспорт принимает имя req.body.username и req.body.password и передает его нашей функции проверки в локальной страtagsи.
- Теперь мы делаем следующее: загружая пользователя из базы данных и проверяя, соответствует ли указанный пароль в базе данных.
- Если все пойдет хорошо, и мы хотим, чтобы пользователь входил в систему, мы вызываем выполненный (null, user).
- Выполнение вызова приведет к возврату streamа в паспорт . Authenticate . Он передал ошибку, пользовательский и дополнительный информационный объект (если он определен).
- Если пользователь был передан, промежуточное программное обеспечение будет вызывать req.login (функция паспорта, прилагаемая к запросу).
- Это вызовет наш метод паспорт.serializeUser, который мы определили ранее.
- Express загружает данные сеанса и присоединяет его к req. Поскольку паспорт хранит сериализованного пользователя в сеансе
- pass.session – это страtagsя паспортов, которая загружает объект пользователя на req.user, если на сервере был найден сериализованный пользовательский объект.
- паспорт.инициализация вызывается по запросу, он находит прикрепленный к сессии паспорт. Затем вызывается pass.session.
- Паспорт.session middleware вызывает паспорт.deserializeUser, который мы установили. Присоединение загруженного пользовательского объекта к запросу как req.user.
Я надеюсь, что это помогает.
Поскольку вы используете PassportJS, поэтому я предполагаю, что вы должны иметь представление о том, как это работает. Поэтому я бы добавил дополнительную информацию, которая, я думаю, очистит ваши сомнения.
Конфигурация паспорта включает в себя три части:
Ответ на ваш вопрос лежит на 3-й части, сеансах.
Если аутентификация завершается успешно, сеанс будет создан и поддерживается с помощью набора файлов cookie в браузере пользователя. Каждый последующий запрос не содержит учетных данных, а скорее уникального файла cookie, который идентифицирует сеанс. Чтобы поддерживать сеансы входа в систему, Passport будет сериализовать и десериализовать user
экземпляры в сеансе и из него.
Согласно вашей реализации, для сеанса сериализуется только идентификатор пользователя, сохраняя объем данных, хранящихся в сеансе, небольшим. Когда поступают последующие запросы, этот идентификатор используется для поиска пользователя, который будет восстановлен в req.user
В паспортах нам предоставляется возможность написать собственную логику сериализации и десериализации, чтобы мы могли выбрать любую подходящую базу данных и не привязаны строгими правилами.
Итак, чтобы подвести итог, после успешной аутентификации пользовательский объект сериализуется и хранится в сеансе, если вы вызываете req.user , тогда вы сможете получить один и тот же пользовательский объект.