1

我使用 ExpressJS 的 Passport 中间件,但我找不到同时使用 passport-local 策略和 passport-facebook 策略的方法。我想设置它,以便用户在我的网站上创建一个帐户,然后,如果他们愿意,他们可以登录 facebook,这样你就可以看到你的朋友也在使用该网站。但是,当返回 facebook api 数据时,我不知道登录用户是什么。

当有人创建帐户时,他们的数据(用户名、电子邮件等)存储在数据库中。当他们随后登录 facebook 时,我只想更新数据库和会话,以现在包含 Facebook API 返回的一些信息(facebookID、AccessToken 等)。如何做到这一点?

这是我可以用来访问返回的 facebook 数据的代码。仅当数据库条目之前已经与 facebook 同步时,User.findOne 行才有效。有什么方法可以传递 req.session 数据来识别当前登录的用户是什么并更新他们的个人资料?

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback",
    //callbackURL: "http://localhost:3000"
    profileFields: ['id', 'displayName']
  },
  function(accessToken, refreshToken, profile, done) {
    User.findOne({facebookID: profile.id}, function(err, user) {
      if (err) { return done(err); }
      user.facebookID = profile.id;
      user.facebookToken = accessToken;
      user.save();
      return done(null, user);
    });
  }
));
4

2 回答 2

0

要获取当前登录的用户,您需要将passReqToCallback : true选项添加到 facebookStrategy

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback",
    //callbackURL: "http://localhost:3000"
    profileFields: ['id', 'displayName'],

    passReqToCallback : true // NEED THIS!!

  },
  function(req, accessToken, refreshToken, profile, done) {
    if (req.user) {
      User.findOne({username: req.user.username}, function(err, user) {
        if (err) { return done(err); }
        user.facebookID = profile.id;
        user.facebookToken = accessToken;
        user.save();
        return done(null, user);
      });
    }
    else{
      console.log("attempted facebook auth from non-logged in user");
      return done(null, null);    
    }
  }
));
于 2014-07-12T23:48:01.763 回答
0

我不熟悉护照的 facebook 模块,但我认为您可以在其中访问本地用户数据库:

  function(accessToken, refreshToken, profile, done) {
    User.findOne({facebookID: profile.id}, function(err, user) {
      if (err) { return done(err); }
      user.facebookID = profile.id;
      user.facebookToken = accessToken;
      user.save();
      return done(null, user);
    });

这样的事情应该没问题:

  var User = require('./models/user');
  passport.use(User.createStrategy());
  passport.serializeUser(User.serializeUser());
  passport.deserializeUser(User.deserializeUser());


  function(accessToken, refreshToken, profile, done) {
    //Make sure you have your user's email field and match that with 
    //the email field you got from Facebook

    User.findOne({email: profile.email}, function(err, user) {
      if (err) { return done(err); }
      user.facebookID = profile.id;
      user.facebookToken = accessToken;
      user.save();
      return done(null, user);
    });

我不确定是否profile有电子邮件字段,但我认为应该在个人资料中的某个位置。

但是,我知道如果您的用户只有用户名和密码,这将不起作用。

于 2014-07-12T17:55:17.167 回答