【问题标题】:PassportJS - Custom Callback and set Session to falsePassportJS - 自定义回调并将 Session 设置为 false
【发布时间】:2014-09-30 00:41:26
【问题描述】:

是否可以使用自定义回调并禁用会话?在文档中,它显示了如何禁用会话和自定义回调,但我如何组合它们?

app.get('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }

    req.logIn(user, function(err) {

      // I'm getting an error here
      // [Error: Failed to serialize user into session]

      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});

【问题讨论】:

    标签: node.js session express passport.js


    【解决方案1】:

    你试过直接组合它们吗? 类似的东西:

    passport.authenticate('local', { "session": false }, function(err,user,info){
       //blablabla
    });
    

    从护照的源代码中,authenticate 定义如下:

    Authenticator.prototype.authenticate = function(strategy, options, callback) {
    

    所以我不明白为什么你不能同时使用这两个参数。

    【讨论】:

    • 这是不正确的(至少对于当前的 Passport)。会话参数需要按照@marekozw 的回答与登录方法一起传递。
    【解决方案2】:

    请确保您使用最新版本的passport(今天是0.2.1)。

    请尝试将{ session: false } 作为req.logIn() 函数的第二个参数传递:

    app.get('/login', function (req, res, next) {
      passport.authenticate('local', function (err, user, info) {
        if (err) { return next(err); }
        if (!user) { return res.redirect('/login'); }
    
        req.logIn(user, { session: false }, function (err) {
    
          // Should not cause any errors
    
          if (err) { return next(err); }
          return res.redirect('/users/' + user.username);
        });
      })(req, res, next);
    });
    

    原因:

    乍一看,在passport.authenticate() 中传递{ session: false } 似乎是合理的,因为该方法的源代码如下:

    Authenticator.prototype.authenticate = function(strategy, options, callback) {
      return this._framework.authenticate(this, strategy, options, callback);
    };
    

    所以它应该能够尊重第二个参数。但是,如果您开始深入了解函数调用堆栈,您会发现options 参数的session 属性被完全忽略了。我的意思是,里面没有提到options.session

    this._framework.authenticate(this, strategy, options, callback);
    

    功能。

    所以基本上你想在req.logIn() 函数中传递它。该函数源码如下:

    req.logIn = function(user, options, done) {
      if (!this._passport) throw new Error('passport.initialize() middleware not in use');
    
      if (!done && typeof options === 'function') {
        done = options;
        options = {};
      }
      options = options || {};
      var property = this._passport.instance._userProperty || 'user';
      var session = (options.session === undefined) ? true : options.session;
    
      this[property] = user;
      if (session) { // HERE! It will not try to serialize anything if you pass {session: false}
        var self = this;
        this._passport.instance.serializeUser(user, function(err, obj) {
          if (err) { self[property] = null; return done(err); }
          self._passport.session.user = obj;
          done();
        });
      } else {
        done && done();
      }
    }
    

    附:请考虑使用npm install [package-name] --save 安装您的npm 依赖项,而不是手动创建package.jsonnpm 会自动获取最新的稳定版本。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 2017-11-06
    • 2016-04-24
    • 1970-01-01
    相关资源
    最近更新 更多