为什么我必须使用 PassportJS 为会话序列化用户对象属性?

Why do I have to serialize user object properties with PassportJS for sessions?

任何人都可以详细解释一下,或者至少参考一个很好的解释这是如何工作的。为什么我必须序列化(字节流)user.id 或用户对象的任何道具才能将其作为 cookie 存储在客户端上?

    passport.serializeUser(function (user, done) {
        done(null, user.id);
    });

    passport.deserializeUser(function (id, done) {
        connection.query("SELECT * FROM users WHERE id = ?", [id], function (err, rows) {
            //verify callback invokes .done()
            done(err, rows[0]);
        });
    });

序列化和反序列化用户对象的原因是,您不必跟踪客户端的状态(已验证或未验证),同时也不必将敏感数据(如密码哈希或原始密码)放在客户的设备。此外,您不必通过可能不安全的连接传输可能敏感的数据。更好的是,由于序列化数据只是一个id,这意味着传输的数据更少。

原则上,您不必这样做,但大多数 Web 应用程序框架都采用这种方法(Django 的 auth for example)。护照也不例外。

无需深入探讨 Passport 的实际运作方式,其工作方式是您必须通过无状态协议记录应用程序的状态。跟踪身份验证、授权和身份的方法是发送某种令牌(如用户 ID)来告诉服务器我就是我所说的那个人,这样我就不用在每次发出请求时都登录了.

现在,对于 Passport,documentation makes some assertions on the pattern one could use to handle the creation of sessions. You can, however, have any procedure you like to handle the serialization, deserialization process. As pointed out in a comment, you wouldn't want to send the actual user ID down the wire - instead you should let your session middleware like express-session 中描述的序列化过程负责实现逻辑。

当您可能有 100 或更多的登录用户时,您不想将整个用户对象存储在 ram 中,因此您只想记住能够查找 该信息稍后 if/when 您需要它。 serialize() 是您决定将什么保留在 ram 中的方式,deserialize() 是您稍后在需要时取回所有丢弃数据的方式。

我已经评论了你的原始代码来说明。

// what minimal info can i record to look up this user later?
passport.serializeUser(function (user, done) { 
    done(null, user.id); // a user id is enough. let's go with that.
});

// some user came back and they are making a request. All I have is this lousy ID. How do I look up the rest of the data I need?
passport.deserializeUser(function (id, done) {

    // let's look them up in the database.
    connection.query("SELECT * FROM users WHERE id = ?", [id], function (err, rows) {
        //verify callback invokes .done()
        done(err, rows[0]); 
    });
});

以上所有只是设置和读取res.session。会话如何保存或与 cookie 匹配是无关的。 Express-session 是一个通用库,但还有其他库。