passport.session()中间件有什么作用?

Geo*_*ker 108 authentication session node.js express passport.js

我正在使用Passport.js使用Easy Node Authentication:Setup and Local教程构建一个身份验证系统.

我很困惑passport.session().

在使用不同的中间件后,我开始明白这express.session()是通过cookie向客户端发送会话ID的内容,但我很困惑passport.session()除了之外需要什么以及为什么需要它express.session().

以下是我设置应用程序的方法:

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

//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);
Run Code Online (Sandbox Code Playgroud)

lin*_*ean 112

passport.session() 充当中间件以改变req对象并将当前为会话ID的"用户"值(从客户端cookie)更改为真正的反序列化用户对象.

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

app.use(passport.session());
Run Code Online (Sandbox Code Playgroud)

相当于

app.use(passport.authenticate('session'));
Run Code Online (Sandbox Code Playgroud)

其中'session'指的是与passportJS捆绑在一起的以下策略.

https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

特别是第59-60行:

var property = req._passport.instance._userProperty || 'user';
req[property] = user;
Run Code Online (Sandbox Code Playgroud)

它本质上充当中间件并在req对象中更改'user'属性的值以包含用户的反序列化标识.要使其正常工作,您必须在自定义代码中包含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);
    });
});
Run Code Online (Sandbox Code Playgroud)

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

  • 我注意到,会话策略是否能够恢复身份验证并反序列化用户。但尽管如此,身份验证仍然转向下一个策略,在我的场景中是 facebook auth。我想知道如果即使会话能够恢复用户,它仍然继续调用以下策略,那么会话策略的意义何在。 (3认同)

Jos*_* C. 14

文档中

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

会议

在典型的Web应用程序中,用于验证用户的凭据仅在登录请求期间传输.如果验证成功,将通过用户浏览器中设置的cookie建立和维护会话.

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

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

  • 感谢您的快速回复,但这并没有回答我的问题。另外,请注意,如果您有一个 express 应用程序并使用 express.session(),那么在任何连接到您的 express 服务器的客户端上(无论他是否经过身份验证),他都会通过 cookie 获得一个会话。这与他是否在您的应用程序的登录保护页面中无关。我仍然想知道这两个中间件之间的区别。 (2认同)
  • @GeorgesKrinker 这是serializeUser() 和deserializeUser 方法。快速中间件将恢复会话信息,但这不一定与护照如何管理用户信息有关。这必须在会议通过快速补水后完成。 (2认同)

小智 10

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

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

并且要使用这个命名的策略session,只需使用一个简单的快捷方式app.use(passport.session()).另请注意,由于显而易见的原因,此特定策略将要求您实现序列化和反序列化函数.


Jar*_*son 9

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

passport.authenticate('session');
Run Code Online (Sandbox Code Playgroud)

在这里的代码中可以看到:

https://github.com/jaredhanson/passport/blob/master/lib/authenticator.js#L236

  • 是的,它在每个请求上运行.Express生成的会话ID是唯一ID,大致相当于浏览器随每个请求发送的身份验证令牌.存储在此会话中的数据用于恢复用户的身份验证状态. (6认同)
  • 你什么意思?它在每个请求上运行,并且不一定具有任何凭据进行身份验证.你介意给我一些关于每个请求所发生的工作流程的更多细节吗? (5认同)