Memahami passport serialisasi deserialize

337

Bagaimana Anda menjelaskan alur kerja metode serialisasi dan deserialisasi Paspor kepada orang awam.

  1. Ke mana perginya user.idsetelah passport.serializeUserdipanggil?

  2. Kami memanggil passport.deserializeUsersetelah itu di mana itu cocok dalam alur kerja?

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

Saya masih mencoba untuk membungkus kepala saya di sekitarnya. Saya memiliki aplikasi yang berfungsi lengkap dan tidak mengalami kesalahan apa pun.

Saya hanya ingin mengerti apa yang sebenarnya terjadi di sini?

Bantuan apa pun dihargai.

Anubhav
sumber

Jawaban:

452
  1. Ke mana perginya user.idsetelah passport.serializeUserdipanggil?

ID pengguna (Anda berikan sebagai argumen kedua dari donefungsi) disimpan dalam sesi dan kemudian digunakan untuk mengambil seluruh objek melalui deserializeUserfungsi.

serializeUsermenentukan data objek pengguna mana yang harus disimpan dalam sesi. Hasil dari metode serializeUser dilampirkan pada sesi sebagai req.session.passport.user = {}. Di sini misalnya, itu akan (karena kami memberikan id pengguna sebagai kunci)req.session.passport.user = {id: 'xyz'}

  1. Kami memanggil passport.deserializeUsersetelah itu di mana itu cocok dalam alur kerja?

Argumen pertama deserializeUserterkait dengan kunci objek pengguna yang diberikan ke donefungsi (lihat 1.). Jadi seluruh objek Anda diambil dengan bantuan kunci itu. Kunci itu di sini adalah id pengguna (kunci dapat berupa kunci apa saja dari objek pengguna yaitu nama, email, dll). Dalam deserializeUserkunci itu cocok dengan array memori / database atau sumber daya data apa pun.

Objek yang diambil dilampirkan ke objek permintaan sebagai req.user

Aliran Visual

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   
});
AB
sumber
2
Jadi user.iddisimpan sebagai req.session.passport.useratau usersendiri disimpan sebagaireq.session.passport.user
Anubhav
@ AB Saya menulis kode untuk menemukan pengguna dari id yang telah diteruskan ke metode deserialize sebagai parameter pertama. Tetapi dalam setiap permintaan itu mengambil pengguna dari db. Ini membuat kehilangan kinerja untuk db. Apa lagi yang harus saya tulis untuk fungsi deserialize untuk memeriksa apakah ada pada sesi atau tidak?
uzay95
2
@ AB Saya tidak mengerti apa yang Anda sarankan untuk uzay95. Jadi dalam sesi saya, saya hanya memiliki user._id. Tetapi pada setiap permintaan, saya harus menggunakan id itu untuk deserialized dari database alias findUserByID dan itu akan memasukkannya ke req.user. Bagaimana saya menghindari melakukan panggilan seperti itu pada setiap permintaan?
Zanko
10
@Zanko Anda dapat memasukkan seluruh objek pengguna ke dalam data sesi, tetapi itu biasanya bukan ide yang baik karena dapat memiliki efek samping lainnya. Misalnya, ketika pengguna memperbarui nama pengguna, Anda juga harus memperbarui data sesi, jika tidak, Anda akan mendapatkan tiket karena "fitur ganti nama yang rusak". Itu contoh yang relatif tidak berbahaya. Hal yang sama dapat terjadi dengan bit izin atau data sensitif yang sama (Ups ...). Pada dasarnya masalah yang sama Anda selalu mengalami jika Anda memiliki data duplikat. TL; DR - Jangan lakukan itu.
Max Truxa
1
Jika saya tidak salah, req.session.passport.user = {id: '..'}bagian dari diagram adalah sedikit off, dan harus req.session.passport.user = 785352sebaliknya, di mana 785352adalah user.id. Saya mengalami masalah saat masuk log untuk membuktikannya, tetapi sepertinya masuk akal. Saat Anda menelepon done(null, user.id);, masuk akal untuk mengambil argumen kedua - user.iddalam hal ini - dan menugaskannya req.session.passport.user, alih-alih menugaskannya req.session.passport.user.id. Karena bagaimana jika sebaliknya Anda masuk user? req.sesssion.passport.user.id = usertidak masuk akal.
Adam Zerner
21

Untuk siapa saja yang menggunakan Koa dan paspor-koa :

Ketahuilah bahwa kunci untuk pengguna yang ditetapkan dalam metode serializeUser (seringkali id ​​unik untuk pengguna itu) akan disimpan di:

this.session.passport.user

Ketika Anda mengatur di done(null, user)deserializeUser di mana 'pengguna' adalah beberapa objek pengguna dari database Anda:

this.req.user ATAU this.passport.user

untuk beberapa alasan, this.userkonteks Koa tidak pernah diset ketika Anda memanggil selesai (null, pengguna) dalam metode deserializeUser Anda.

Jadi Anda dapat menulis middleware Anda sendiri setelah panggilan ke app.use (passport.session ()) untuk memasukkannya ke dalam pengguna ini seperti:

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

Jika Anda tidak jelas tentang cara kerja serializeUser dan deserializeUser, tekan saja saya di twitter. @Yvanscher

yvanscher
sumber
Maaf untuk necroposting di sini, tetapi saya memiliki kekhawatiran sekarang setelah membaca penjelasan deserialize. Saya telah memposting pertanyaan tentang ini di sini di SO: stackoverflow.com/questions/54154047/...
Peter Kellner
Sangat membantu, tetapi masih mengalami beberapa masalah saat membaca pengguna dari rute lain. Adakah yang bisa membantu saya di sini? stackoverflow.com/questions/60709882/…
Harry Lincoln