Розуміння паспорта серіалізувати десеріалізувати


337

Як би ви пояснили мирянину робочий процес методів серіалізації та десеріалізації Passport.

  1. Куди user.idйде після того, passport.serializeUserяк було викликано?

  2. Ми дзвонимо passport.deserializeUserодразу після цього, куди воно вписується в робочий процес?

    // 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);
        });
    });

Я все ще намагаюся обмотати голову навколо цього. У мене є повноцінний робочий додаток, і я не стикаюся з помилками.

Я просто хотів зрозуміти, що саме тут відбувається?

Будь-яка допомога вдячна.

Відповіді:


452
  1. Куди user.idйде після того, passport.serializeUserяк було викликано?

Ідентифікатор користувача (ви надаєте як другий аргумент doneфункції) зберігається в сеансі і пізніше використовується для отримання всього об’єкта через deserializeUserфункцію.

serializeUserвизначає, які дані об’єкта користувача слід зберігати в сеансі. Результат методу serializeUser додається до сеансу як req.session.passport.user = {}. Наприклад, це було б (оскільки ми надаємо ідентифікатор користувача як ключ)req.session.passport.user = {id: 'xyz'}

  1. Ми дзвонимо passport.deserializeUserодразу після цього, куди воно вписується в робочий процес?

Перший аргумент deserializeUserвідповідає ключу об’єкта користувача, який був наданий doneфункції (див. 1.). Таким чином, весь об’єкт буде отриманий за допомогою цього ключа. Цей ключ тут - ідентифікатор користувача (ключовим може бути будь-який ключ об’єкта користувача, тобто ім'я, електронна пошта тощо). У deserializeUserцьому ключі узгоджується масив / база даних пам'яті або будь-який ресурс даних.

Вибраний об'єкт додається до об'єкта запиту як req.user

Візуальний потік

passport.serializeUser(function(user, done) {
    done(null, user.id);
});              
                  
                 
                 └─────────────────┬──→ saved to session
                                       req.session.passport.user = {id: '..'}
                                   
                                              
passport.deserializeUser(function(id, done) {
                   ┌───────────────┘
                   
                    
    User.findById(id, function(err, user) {
        done(err, user);
    });            └──────────────→ user object attaches to the request as req.user   
});

2
Так user.idзберігається як req.session.passport.userабо userзберігається якreq.session.passport.user
Анубхав

@AB Я написав код, щоб знайти користувача з ідентифікатора, переданого методу десеріалізації в якості першого параметра. Але в кожному запиті це витяг користувача з db. Це робить втрату продуктивності для db. Що ще потрібно написати для десериалізації функції, щоб перевірити, чи існує вона на сеансі чи ні?
uzay95

2
@AB Я не розумію, що ви запропонували uzay95. Тож у своєму сеансі я маю лише user._id. Але в кожному запиті я повинен використовувати цей ідентифікатор для десеріалізації з бази даних aka findUserByID, і це поставить його в req.user. Як я можу уникати такого дзвінка на кожен запит?
Занько

10
@Zanko Ви можете помістити цілий об’єкт користувача у дані сеансу, але це, як правило, не дуже добре, оскільки це може мати інші побічні ефекти. Наприклад, коли користувач оновлює своє ім’я користувача, вам доведеться також оновити дані сеансу, інакше ви отримаєте квитки через "функцію зламаного перейменування". Це відносно нешкідливий приклад. Те саме може статися з дозволами або рівними конфіденційними даними (На жаль ...). По суті ті самі проблеми, з якими ви завжди стикаєтесь, якщо у вас є дублікати даних. TL; DR - Не роби цього.
Макс Трукса

1
Якщо я не помиляюся, req.session.passport.user = {id: '..'}частина діаграми трохи відключена, і повинна бути req.session.passport.user = 785352замість цього, де 785352є user.id. У мене виникають проблеми з реєстрацією консолі, щоб довести це, але, схоже, це мало б сенс. Коли ви телефонуєте done(null, user.id);, було б доцільно взяти другий аргумент - user.idв даному випадку - і призначити його req.session.passport.user, а не призначати req.session.passport.user.id. Бо що робити, якщо ти замість цього пройдеш user? req.sesssion.passport.user.id = userне було б сенсу.
Адам Зернер

21

Для всіх, хто використовує Коа та коа-паспорт :

Знайте, що ключ для користувача, встановлений у методі serializeUser (часто це унікальний ідентифікатор для цього користувача), буде зберігатися у:

this.session.passport.user

Коли ви done(null, user)входите в deserializeUser, де 'user' є деяким користувацьким об’єктом із вашої бази даних:

this.req.user АБО this.passport.user

чомусь this.userконтекст Koa ніколи не встановлюється, коли ви зателефонуєте виконати (null, user) у вашому методі deserializeUser.

Таким чином, ви можете написати власне проміжне програмне забезпечення після виклику до app.use (passport.session ()), щоб розмістити його в this.user так:

app.use(function * setUserInContext (next) {
  this.user = this.req.user
  yield next
})

Якщо вам незрозуміло, як працюють serializeUser та deserializeUser, просто натисніть на Twitter. @yvanscher


Вибачте за некропостинг тут, але я вже хвилююся після прочитання пояснення про деаріалізацію. Я опублікував питання про це тут на SO: stackoverflow.com/questions/54154047/…
Пітер Кельнер

Супер корисно, але все ж виникають проблеми з читанням користувача з інших маршрутів. Хтось може мені тут допомогти? stackoverflow.com/questions/60709882/…
Гаррі Лінкольн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.