使用带护照本地的护照Facebook策略时无法将用户序列化到会话中

Posted

技术标签:

【中文标题】使用带护照本地的护照Facebook策略时无法将用户序列化到会话中【英文标题】:Failed to serialize user into session when using passport-facebook strategy with passport-local 【发布时间】:2015-06-17 16:11:36 【问题描述】:

我在sails.js 中使用passport-localpassport-facebook 策略进行身份验证。使用电子邮件进行身份验证工作正常。但是当用户使用 facebook 进行身份验证时,我收到此错误消息 [Error: Failed to serialize user into session]

然后我测试了serializeUser 方法,结果发现user 参数在facebook 的情况下为空。虽然我也尝试查看是否调用了 verifyHandler 并且没有调用它。

这是我的 facebook 身份验证操作代码:

facebook: function (req, res) 

    passport.authenticate('facebook', failureRedirect: '/login', scope: ['email'], function (err, user) 

      if ((err) || (!user)) 
        req.session.flash = 
          errMsg: 'Email or password mismatch.'
        

        return res.redirect('/login');
      

      req.logIn(user, function (err) 
        if (err) 
          console.log(err);
          res.view('500');
          return;
        

        res.redirect('/');
        return;
      );
    )(req, res);

  

这是passport.js服务的代码(api/services/passport.js)

var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
  FacebookStrategy = require('passport-facebook').Strategy,
  bcrypt = require('bcrypt');


var verifyHandler = function (token, tokenSecret, profile, done) 

  console.log('in verifyHandler'); // this line is not being executed.
  console.log(profile);

  process.nextTick(function () 

    User.findOne(uid: profile.id, function (err, user) 

      if (err) 
        return done(err);
      

      if (user) 

        return done(null, user);

       else 

        var data = 
          provider: profile.provider,
          uid: profile.id,
          name: profile.displayName
        ;

        if (profile.emails && profile.emails[0] && profile.emails[0].value) 
          data.email = profile.emails[0].value;
        

        User.create(data, function (err, user) 
          return done(err, user);
        );
      
    );
  );
;

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

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

passport.use(new LocalStrategy(
    usernameField: 'email',
    passwordField: 'password'
  ,
  function (email, password, done) 

    User.findOne(email: email).exec(function (err, user) 
      if (err) 
        return done(err);
      
      if (!user) 
        return done(null, false, message: 'Unknown user ' + email);
      

      bcrypt.compare(password, user.password, function (err, res) 
        if (!res) return done(null, false, message: 'Invalid Password');
        return done(null, user);
      );

    );
  
));

passport.use(new FacebookStrategy(
  clientID: sails.config.facebook.clientID,
  clientSecret: sails.config.facebook.clientSecret,
  callbackURL: sails.config.facebook.callbackURL
, verifyHandler));

最后是(config/passport.js)

var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
  FacebookStrategy = require('passport-facebook').Strategy;

module.exports = 
  http: 
    customMiddleware: function (app) 
      app.use(passport.initialize());
      app.use(passport.session());
    
  
;

有什么想法吗?

【问题讨论】:

【参考方案1】:

检查 user.id 是否已定义并且它是字符串但不是 ObjectId()。

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

【讨论】:

以上是关于使用带护照本地的护照Facebook策略时无法将用户序列化到会话中的主要内容,如果未能解决你的问题,请参考以下文章

使用 passport.js 将本地策略连接到另一个(Facebook、Twitter、Google 等)

护照本地策略没有被调用

混合护照-facebook和护照-jwt的最佳方法是啥?

Passport.js:passport-facebook-token 策略,通过 JS SDK 登录然后验证护照?

无法使用 facebook 的护照成功重定向

未知的身份验证策略护照