【问题标题】:What does passport.session() middleware do?passport.session() 中间件有什么作用?
【发布时间】:2014-03-29 22:08:44
【问题描述】:

我正在使用 Passport.js 使用 Easy Node Authentication: Setup and Local tutorial 构建身份验证系统。

我对 passport.session() 的作用感到困惑。

在玩弄了不同的中间件之后,我了解到 express.session() 是通过 cookie 向客户端发送会话 ID,但我对 passport.session() 的作用以及为什么除了 @ 之外还需要它感到困惑987654325@.

这是我设置应用程序的方式:

// Server.js 配置应用程序并设置网络服务器

//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

var configDB = require('./config/database.js');

//Configuration of Databse and App

mongoose.connect(configDB.url); //connect to our database

require('./config/passport')(passport); //pass passport for configuration

app.configure(function() {

    //set up our express application

    app.use(express.logger('dev')); //log every request to the console
    app.use(express.cookieParser()); //read cookies (needed for auth)
    app.use(express.bodyParser()); //get info from html forms

    app.set('view engine', 'ejs'); //set up ejs for templating

    //configuration for passport
    app.use(express.session({ secret: 'olhosvermelhoseasenhaclassica', maxAge:null })); //session secret
    app.use(passport.initialize());
    app.use(passport.session()); //persistent login session
    app.use(flash()); //use connect-flash for flash messages stored in session

});

//Set up routes
require('./app/routes.js')(app, passport);

//launch
app.listen(port);
console.log("Server listening on port" + port);

【问题讨论】:

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


    【解决方案1】:

    来自documentation

    在基于 Connect 或 Express 的应用程序中,passport.initialize() 需要中间件来初始化 Passport。如果您的应用程序 使用持久登录会话,passport.session() 中间件必须 也可以使用。

    会话

    在典型的 Web 应用程序中,用于验证 用户只会在登录请求期间传输。如果 身份验证成功,将建立并维护一个会话 通过在用户浏览器中设置的 cookie。

    每个后续请求都不会包含凭据,而是 标识会话的唯一 cookie。为了支持登录 会话,Passport 将序列化和反序列化用户实例以 并从会话中。

    请注意,启用会话支持是完全可选的,尽管它是 推荐用于大多数应用程序。如果启用,请务必使用 express.session() 在 passport.session() 之前确保登录 会话以正确的顺序恢复。

    【讨论】:

    • 感谢您的快速回复,但这并不能回答我的问题。另外,请注意,如果您有一个 express 应用程序并使用 express.session(),则在任何连接到您的 express 服务器的客户端上(无论他是否经过身份验证),他都将通过 cookie 获得会话。这与他是否在您的应用程序的登录保护页面中无关。我还是想知道这两个中间件的区别。
    • @GeorgesKrinker 它是 serializeUser() 和 deserializeUser 方法。 express 中间件将恢复会话信息,但这不一定与护照如何管理用户信息有关。这必须在会话通过 express 补水后完成。
    • 好吧,我的印象是 serializeUser() 和 deserializeUser 方法在路由中的 authenticate() 上运行。
    • @GeorgesKrinker 我不这么认为。当我使用护照时,我只在登录时调用了 .authenticate。
    • app.post('/login', passport.authenticate('local'), ...
    【解决方案2】:

    它只是验证会话(由express.session() 填充)。相当于:

    passport.authenticate('session');
    

    从这里的代码可以看出:

    https://github.com/jaredhanson/passport/blob/42ff63c/lib/authenticator.js#L233

    【讨论】:

    • 什么意思?它在每个请求上运行,并且不一定有任何凭据来进行身份验证。您介意给我详细介绍一下每个请求所发生的工作流程吗?
    • 是的,它在每个请求上运行。 Express 生成的会话 ID 是一个唯一 ID,大致相当于浏览器随每个请求发送的身份验证令牌。该会话中存储的数据用于恢复用户的身份验证状态。
    • 你好@JaredHanson 你能看看this。我在任何地方都找不到答案?
    • @JaredHanson 我正在尝试使用 passport.js 与广泛使用的符合 OAuth2 的开源授权服务器进行身份验证。但我收到一个错误。你愿意帮助解决问题吗?这是链接:stackoverflow.com/questions/38176236/…
    • @JaredHanson:我观察到的是,在通过 google-oauth 登录后使用 passport.user 信息增强的 req 对象在网站上完成下一个新页面请求时丢失。这是预期的行为吗?那我不知道怎么找回最近登录的用户信息了?
    【解决方案3】:

    虽然您将使用PassportJs 作为登录 URL 的一部分来验证用户,但您仍然需要一些机制来将此用户信息存储在会话中并在每个后续请求中检索它(即序列化/反序列化用户) .

    因此,实际上,您正在对每个请求的用户进行身份验证,即使此身份验证不需要像在登录响应中那样查找数据库或 oauth。因此,passport 将会话身份验证也视为另一种身份验证策略。

    要使用这个名为 session 的策略,只需使用一个简单的快捷方式 - app.use(passport.session())。另请注意,出于显而易见的原因,此特定策略将希望您实现序列化和反序列化功能。

    【讨论】:

      【解决方案4】:

      passport.session() 充当中间件来更改 req 对象并将当前作为会话 ID(来自客户端 cookie)的“用户”值更改为真正的反序列化用户对象。

      虽然其他答案提出了一些很好的观点,但我认为可以提供一些更具体的细节。

      app.use(passport.session());
      

      等价于

      app.use(passport.authenticate('session'));
      

      其中“会话”指的是与 passportJS 捆绑在一起的以下策略。

      这是文件的链接: https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

      在撰写本文时,permalink 指向以下行:

      var property = req._passport.instance._userProperty || 'user';
      req[property] = user;
      

      它本质上充当中间件并更改 req 对象中“用户”属性的值以包含用户的反序列化身份。要使其正常工作,您必须在自定义代码中包含 serializeUserdeserializeUser 函数。

      passport.serializeUser(function (user, done) {
          done(null, user.id);
      });
      
      passport.deserializeUser(function (user, done) {
          //If using Mongoose with MongoDB; if other you will need JS specific to that schema.
          User.findById(user.id, function (err, user) {
              done(err, user);
          });
      });
      

      这将从数据库中找到正确的用户并将其作为闭包变量传递给回调done(err,user);,因此passport.session()中的上述代码可以替换req对象中的'user'值并传递给堆中的下一个中间件。

      【讨论】:

      • 嘿,我怎样才能在会话中存储用户详细信息,我不想直接将它们存储在数据库中
      • “在请求标头中”?不只是在请求对象中
      • 我注意到如果会话策略能够恢复身份验证并反序列化用户。但尽管如此,身份验证仍然转移到下一个策略,在我的场景中是 facebook auth。我想知道即使会话能够恢复用户,会话策略仍然继续调用以下策略有什么意义。
      猜你喜欢
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2018-10-24
      • 2018-06-21
      相关资源
      最近更新 更多