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