好的,我刚刚进入MEAN堆栈,我正在尝试使用Passport.js构建应用程序。
我只是开始用户序列化来维护会话。在他们的示例中,Passport使用它进行序列化和反序列化:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
所以,我的问题是:这个例子被认为是安全的吗?如果我理解这一点,那是不是意味着客户可以伪装用户ID以便以具有该ID的用户身份登录?
我想我要问的是,他们的例子被认为是"安全"和正确的做事方式,或者是否期望您将更改这些功能以生成唯一的序列化。如果这被认为是安全的,那么我想我错过了一些关于它是如何工作的东西,而且我很乐意被填补。
另一方面,如果这不安全并且我希望用自己的函数来代替这些函数,那么以下是一种有效且安全的方法:
如果我的逻辑直到这里有效,那么生成这个随机散列的正确方法是什么?
答案 0 :(得分:2)
是的,这就是你如何进行序列化/反序列化。未收到客户的id
。
会话信息存储在本地会话存储中,例如。数据库,随机ID下。例如,express-session
使用uid-safe生成会话ID。此ID设置为cookie,然后发送给客户端。
当客户端发出请求时,如果cookie未被篡改,则会从cookie中读取会话ID(通常,ID是使用您在初始化会话时定义的secret
签名的)。使用此ID,将从本地会话存储中读取实际会话数据。这是反序列化中使用的id
来自的地方。
以下是存储到MongoDB的会话对象的示例:
{
"_id" : "_RXnIfFeb_qH6AXMO2ounrxlJZPHkwda",
"session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"secure\":false,\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"5614c62e4372842244660dcf\"}}"
}
这里的_id
是在cookie中签名和发送的内容。解码为JSON对象的session
字符串为:
{
"cookie": {
"originalMaxAge": null,
"expires": null,
"secure": false,
"httpOnly": true,
"path": "/"
},
"passport": {
"user": "5614c62e4372842244660dcf"
}
}
此处,passport.user
是我的应用seralizeUser
返回的实际用户ID,在加载会话时会向deserializeUser
提供。
那么如果更改cookie内容会发生什么?如果cookie已签名,则它将失效,因为更改的值与签名不匹配。如果未签名,则在查询会话存储时使用该值。查询不会返回任何内容,因为您更改了ID并且数据库中没有匹配的会话(除非您已经找到/猜到了另一个活动会话的会话ID - 即执行session hijacking)。