简体   繁体   English

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

[英]How to properly implement serializeUser with passport.js?

Okay, so I am just getting in to the MEAN stack, and I'm trying to build an app with Passport.js.好的,所以我刚刚进入 MEAN 堆栈,我正在尝试使用 Passport.js 构建一个应用程序。

I'm just starting user serialization to maintain sessions.我刚刚开始用户序列化以维护会话。 In their example, Passport uses this for serialization and deserialization:在他们的示例中,Passport 将其用于序列化和反序列化:

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

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

So, my question is this: is this example considered secure?所以,我的问题是:这个例子被认为是安全的吗? If I understand this right, doesn't that mean that a client could just fake the user ID to become logged in as whichever user has that ID?如果我理解正确,这是否意味着客户端可以伪造用户 ID 以作为拥有该 ID 的任何用户登录?

I guess what I'm asking is, is their example considered "secure" and a proper way of doing things, or is it expected that you will change these functions to generate unique serialization.我想我要问的是,他们的示例是否被认为是“安全的”和正确的做事方式,或者是否期望您将更改这些函数以生成唯一的序列化。 If this is considered secure, then I think I'm missing something on how this works, and I'd love to be filled in.如果这被认为是安全的,那么我想我错过了一些关于它是如何工作的东西,我很乐意被填补。

On the other hand, if this is not secure and I am expected to write my own functions in place of these, would the following be a valid and secure way of doing this:另一方面,如果这不安全,并且希望我编写自己的函数来代替这些函数,那么以下是否是一种有效且安全的方法:

  • Upon serialization of a user, generate a random hash and put that in the user's database entry.在用户序列化后,生成一个随机散列并将其放入用户的数据库条目中。 Random hash is the serial that represents that user.随机散列是代表该用户的序列号。
  • Upon deserialization, look up the random hash in the database and return the corresponding user.反序列化后,在数据库中查找随机散列并返回相应的用户。 If the hash isn't found throw some kind of error.如果未找到散列,则会引发某种错误。
  • When the user logs out, delete their serial hash from their entry in the database.当用户注销时,从他们在数据库中的条目中删除他们的串行哈希。

If my logic up until here is valid, what would be a proper way to generate this random hash?如果我的逻辑直到这里是有效的,那么生成这个随机散列的正确方法是什么?

Yes, that is how you do serialization / deserialization.是的,这就是您进行序列化/反序列化的方式。 The id is not received from the client.未从客户端收到id

Session information is stored to your local session store, eg.会话信息存储到您的本地会话存储,例如。 database, under a random ID.数据库,在一个随机 ID 下。 For example, express-session uses uid-safe to generate the session ID.例如, express-session使用uid-safe来生成会话 ID。 This ID is set to a cookie which is then sent to the client.此 ID 设置为 cookie,然后将其发送给客户端。

When the client makes a request, the session ID is read from the cookie if it has not been tampered (usually the ID is signed with the secret you define when intializing sessions).当客户端发出请求时,如果会话 ID 未被篡改,则会从 cookie 中读取会话 ID(通常,该 ID 使用您在初始化会话时定义的secret签名)。 Using this ID, the real session data is read from your local session store.使用此 ID,从本地会话存储中读取真实会话数据。 This is where the id used in deserialization comes from.这就是反序列化中使用的id来源。

Here is an example what a session object stored to MongoDB could look like:以下是存储到 MongoDB 的会话对象的示例:

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

The _id here is what is signed and sent in the cookie.这里的_id是在 cookie 中签名和发送的。 The session string, decoded to JSON object, is:解码为 JSON 对象的session字符串是:

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

Here, passport.user is the actual user ID returned by my applications seralizeUser that is given to deserializeUser when a session is being loaded.在这里, passport.user是我的应用程序返回的实际用户ID seralizeUser是给予deserializeUser被加载会话时。

So what happens if you change the cookie content?那么如果您更改 cookie 内容会发生什么? If the cookie is signed, it will be invalidated because the altered value does not match the signature.如果 cookie 被签名,它将被无效,因为更改的值与签名不匹配。 If it is not signed, the value is used when querying session store.如果未签名,则在查询会话存储时使用该值。 The query will not return anything because you changed the ID and there is no matching session in the database (unless you have found out / guessed the session ID of another active session - ie. performing session hijacking ).查询不会返回任何内容,因为您更改了 ID 并且数据库中没有匹配的会话(除非您发现/猜测了另一个活动会话的会话 ID - 即执行会话劫持)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM