node.js - 将 Passport-Facebook 策略与 Passport-local 结合使用时,无法将用户序列化到 session 中

标签 node.js sails.js passport.js passport-local passport-facebook

我在 sails.js 中使用 passport-localpassport-facebook 策略进行身份验证。使用电子邮件进行身份验证工作正常。但是当用户使用 facebook 进行身份验证时,我收到此错误消息[错误:无法将用户序列化到 session 中]

然后我测试了 serializeUser 方法,结果发现在 facebook 的情况下 user 参数为空。虽然我也尝试查看 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());
    }
  }
};

有什么想法吗?

最佳答案

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

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

关于node.js - 将 Passport-Facebook 策略与 Passport-local 结合使用时,无法将用户序列化到 session 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29586880/

相关文章:

node.js - 使用 Forever 运行的 NodeJS 应用程序在浏览器中出现 502 错误

javascript - 在 Sails.js 中删除之前确认

javascript - req.isAuthenticated() 重定向时发生变化?

typescript - 如何声明节点请求 session 对象的 typescript 接口(interface)扩展?

MySQL LoopBack 中的多对多关系

node.js - 使用 yeoman 生成终极种子时出错

node.js - 目前最新最好的 socket.io 基准测试模块是什么?

javascript - Sails.js 套接字。好的一面和坏的一面。与 socket.io 的区别

node.js - 如何在 Passport.js 中定义多个 isAuthenticated 函数?

json - Sails.js/Nodejs/Json 对表情符号的支持