如何正确使用passport.js实现serializeUser?

好的,所以我只是进入了MEAN堆栈,我试图用Passport.js构build一个应用程序。

我只是开始用户序列化来维护会话。 在他们的例子中,Passport使用这个序列化和反序列化:

passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); 

所以,我的问题是:这个例子被认为是安全的? 如果我理解了这个权利,那么这不是说客户端可以伪造用户标识以login为具有该标识的用户?

我想我要问的是,他们的例子被认为是“安全的”,是一种正确的做事方式,或者是希望你改变这些function来产生独特的序列化。 如果这被认为是安全的,那么我想我错过了一些关于如何工作的东西,我很乐意填补。

另一方面,如果这是不安全的,我希望自己写一些函数来代替这些函数,那么下面这样做是否有效和安全:

  • 在用户序列化后,生成一个随机散列并将其放入用户的数据库条目中。 随机哈希是代表该用户的序列号。
  • 在反序列化之后,查找数据库中的随机哈希并返回相应的用户。 如果没有发现散列抛出某种错误。
  • 用户注销时,从数据库中的条目中删除其串行散列。

如果直到这里我的逻辑是有效的,那么生成这个随机哈希的正确方法是什么?

是的,这就是你如何做序列化/反序列化。 该id不是从客户端收到的。

会话信息存储在本地会话存储中,例如。 数据库,在一个随机的ID下。 例如, express-session使用uid-safe生成会话ID。 这个ID被设置为一个cookie,然后发送给客户端。

当客户端发出请求时,如果cookie没有被篡改(通常ID是使用您在初始化会话时定义的secret签名),则会从Cookie中读取会话ID。 使用此ID,将从本地会话存储中读取实际会话数据。 这是用于反序列化的id来自哪里。

以下是存储到MongoDB的会话对象的示例:

 { "_id" : "_RXnIfFeb_qH6AXMO2ounrxlJZPHkwda", "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"secure\":false,\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"5614c62e4372842244660dcf\"}}" } 

这里的_id是在cookie中签名和发送的内容。 解码为JSON对象的sessionstring是:

 { "cookie": { "originalMaxAge": null, "expires": null, "secure": false, "httpOnly": true, "path": "/" }, "passport": { "user": "5614c62e4372842244660dcf" } } 

在这里, passport.user是由我的应用程序seralizeUser返回的实际用户ID,在加载会话时向seralizeUser提供。

那么如果您更改cookie内容会发生什么? 如果cookie被签名,则由于修改后的值与签名不匹配而无效。 如果未签名,则在查询会话存储时使用该值。 查询不会返回任何内容,因为您更改了标识,并且数据库中没有匹配的会话(除非您已经发现/猜测了另一个活动会话的会话标识 – 即执行会话劫持 )。