【问题标题】:ExpressJS/PassportJS: Authentication vs. SessionsExpressJS/PassportJS:身份验证与会话
【发布时间】:2014-04-06 20:37:45
【问题描述】:

我刚开始使用 NodeJS(和 Web 编程)并且无法理解身份验证和会话。我阅读了很多教程,就在我认为我拥有它的时候,我感到困惑。我的问题是同时处理身份验证(注册/登录)和持久会话。

我用的是PassportJS,后来看了很多教程,我想我终于在这里找到了一个很棒的:https://scotch.io/tutorials/easy-node-authentication-setup-and-local

但现在我对 serializeUser 和 deserializeUser 如何处理会话感到困惑。对于这个新手问题,请多多包涵,但我的理解是用户 ID 用于跟踪会话。

所以我的问题是:

  1. 用户 ID 是由 Passport 自动生成的吗?
  2. 序列化只是将用户 ID 添加到会话 cookie 中?
  3. 最后,如何更改会话参数,如 maxAge?我应该在哪里设置它们?我对 Express 会话和 Passport 会话有点困惑。

如果有人可以提供一个很好的教程的链接,我也很感激。

谢谢。

【问题讨论】:

    标签: node.js session cookies express passport.js


    【解决方案1】:

    Passport 不直接管理您的会话,它只是使用您的会话。因此,您将根据您使用的中间件配置会话的生命周期。以express自带的cookie中间件为例:

      app.use(express.session({ cookie: { maxAge: 60000 }}));
    

    就 Passport 而言,它不会生成任何东西。它调用您的身份验证、序列化和反序列化函数来查找、加载和重新加载用户数据。流程是这样的:

     passport.use(<new Strategy>(function(username,password,done) { }))
    

    这接受带有用户名和密码值的登录表单提交,该用户名和密码值被传递到您的实现中。通常是生成用户对象(基于您的模型/实现)的数据库查找传递到 done(err,user) 函数。

    现在您已经找到了一个用户对象,它将被设置到请求对象上,但这仅适用于该请求。会话用于序列化用户(通常是用户对象的 ID),以便可以再次传入以重构用户。

     my.serializeUser = function(user,done)
    

    这是 Passport 将您找到的 User 对象传递给您的函数。这是您构造该用户的字符串表示并将其传递给done(err,string) 的地方,您作为第二个参数传递的任何内容都会与会话一起存储。

     my.deserializeUser = function(string,request,done)
    

    这是您的函数,其中密钥(由您的 serializeUser 创建)被传回给您。然后,您的代码使用它来检索完整的用户对象(可能是通过该用户 ID 进行的数据库查询)并将完整的用户对象传回给 done(err,user) 这再次根据您的处理程序的请求设置。

    因此,如何序列化、反序列化和身份验证完全取决于您。 Passport 提供了这些钩子,因此无论您选择何种策略,您都可以以相同的方式对路由设置身份验证要求。

    【讨论】:

    • 非常感谢马特。这说明了一些事情。我现在的问题是,在反序列化用户中,findById() 没有给出实现。这是 Passport 提供的吗?另外,如果我理解正确,当用户登录时,Passport/Express 将创建一个用户对象并将凭据(用户名、密码)存储到该对象中。该对象的 ID(可以跨会话更改)存储在会话 cookie 中。当 logout() 被调用时,这个 User 对象被删除。我接近了吗?
    • 我在 Passport 上看到的大多数示例都假设您使用的是 MongoDB(findOne、findById 等),这只是为了暗示数据库查找和 JSON/JS 对象的返回。如果您愿意,ID 可能会更改,重点是您能够检索必要的数据(权限、电子邮件等),而无需将所有数据存储在会话中。请记住,您的代码是以任何必要的形式创建用户对象的。 Passport 帮助您通过路由处理程序和身份验证链管理对象。注销会将其从会话中删除,但不会删除任何内容。
    • 谢谢马特。我想我已经掌握了一些窍门。我将再次检查代码。我不知道 findById 是一个 Mongo API。这很有帮助。干杯。
    • 没问题。对于许多人来说,Mongo 和 Node 上手速度相当快,因为​​您几乎可以在不需要任何转换的情况下传递数据,因为它们都在 JS 和 JSON 中。如果您想遵循您在文档中找到的模式,Mongoose 是一个典型的包/中间件,用于通过 Node 管理它:mongoosejs.com/docs/2.7.x/docs/finding-documents.html
    • 谢谢马特。我对 User.FineOne() 如何调用 Mongo 仍然有些模糊。但我现在对代码的理解要好得多。感谢您的意见。
    【解决方案2】:

    我可以给你几个链接来更好地理解它。关键是写更好的代码,你必须看到更好的代码。 这个link from AirPair CEO 带来了急需的清晰度,尤其是最后一部分,因为我们现在都使用 Express 4。
    第二个是这个toon.io。这个真的让我大开眼界。我对很多事情仍然不清楚,一旦我变得更清楚,我会补充。 人们在他们的教程中没有提到的一件事是,在生产环境中你不能使用 Express 的传统数据存储。显然 express 还需要维护一个表,它使用了一个叫做 Memory Store 的东西。要使用您自己的会话存储,请参阅here

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 2020-10-06
      • 2020-08-29
      • 2017-01-03
      相关资源
      最近更新 更多