1

我使用ExpressJS的Passport中间件,我找不到同时使用护照本地策略和护照facebook策略的方法。我想设置它,以便用户将在我的网站上创建一个帐户,然后,如果他们想要,他们可以登录到Facebook,以便您可以看到您的朋友谁也使用该网站。但是,我不知道当返回facebook api数据时登录用户是什么。expressjs护照使用Facebook登录和本地登录

当有人创建一个帐户时,他们的数据(用户名,电子邮件等)被存储在数据库中。当他们然后登录到Facebook我想更新数据库和会话,现在包括由Facebook API(facebookID,AccessToken等)返回的一些信息。这怎么能实现?

这里是我可以用来访问返回的Facebook数据的代码。 User.findOne的行仅在数据库条目已经与facebook同步之前工作。 有什么方法可以传递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); 
    }); 
    } 
)); 

回答

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);  
    } 
    } 
)); 
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是否有电子邮件字段,但我认为这应该在个人资料中的某个位置。

但是,我明白,如果您的用户只有用户名和密码,这将无法正常工作。

+0

谢谢您的回复!本地用户确实有电子邮件,但无法确定用户输入的电子邮件将与他们的Facebook电子邮件相同。 – Elementary

+0

也许你可以尝试将'profile'传递给'done',并使用'done'方法用facebookID,电子邮件等渲染一个页面。然后你可以使用会话数据并进行数据库插入。 – paradite

+0

当我尝试这个会话数据也被配置文件json替换。所以我没有以前会话数据的记录 – Elementary