2016-06-22 17 views
1

Ich habe Kurse und Tutorials auf NodeJS für eine Weile genommen und beschlossen, sie in einer App zu nutzen.NodeJS Passport Facebook OAuth

Für dieses Projekt brauche ich Benutzer anmelden und anmelden, um ihre Aktivität in einer Datenbank zu speichern. I-Pass verwendet, um dieses Verfahren zu tun, wird der Code für diesen Abschnitt des Projektes ist folgende:

/****** Passport functions ******/ 
passport.serializeUser(function (user, done) { 
    done(null, user.id); 
}); 

passport.deserializeUser(function (id, done) { 
    db.user.findOne({ where : { idUser : id } }).then(function (err, user) { 
     done(err, user); 
    }); 
}); 

//Facebook 
passport.use(new FacebookStrategy({ 
    //Information stored on config/auth.js 
    clientID: configAuth.facebookAuth.clientID, 
    clientSecret: configAuth.facebookAuth.clientSecret, 
    callbackURL: configAuth.facebookAuth.callbackURL, 
    profileFields: ['id', 'emails', 'displayName', 'name', 'gender'] 

}, function (accessToken, refreshToken, profile, done) { 
    //Using next tick to take advantage of async properties 
    process.nextTick(function() { 
     db.user.findOne({ where : { idUser : profile.id } }).then(function (err, user) { 
      if(err) { 
       return done(err); 
      } 
      if(user) { 
       return done(null, user); 
      } else { 
       db.user.create({ 
        idUser : profile.id, 
        token : accessToken, 
        nameUser : profile.displayName, 
        email : profile.emails[0].value, 
        sex : profile.gender 
       }); 
       return done(null); 
      } 
     }); 
    }); 
})); 

app.use(express.static(__dirname + '/public/')); 

/* FACEBOOK STRATEGY */ 
// Redirect the user to Facebook for authentication. When complete, 
// Facebook will redirect the user back to the application at 
//  /auth/facebook/callback// 
app.get('/auth/facebook', passport.authenticate('facebook', { scope : ['email']})); 
/* FACEBOOK STRATEGY */ 
// Facebook will redirect the user to this URL after approval. Finish the 
// authentication process by attempting to obtain an access token. If 
// access was granted, the user will be logged in. Otherwise, 
// authentication has failed. 
app.get('/auth/facebook/callback', 
    passport.authenticate('facebook', { successRedirect: '/app', 
             failureRedirect: '/' })); 

app.get('/', function (req, res) { 
    res.render('/'); 
}); 

app.get('/app', isLoggedIn, function (req, res) { 
    res.sendFile('app.html'); 
}); 

function isLoggedIn(req, res, next) { 
    if(req.isAuthenticated()) { 
     return next(); 
    } else { 
     res.redirect('/'); 
    } 
} 

Die Tutorial ich auf Facebook Auth unter Verwendung von Passport so ziemlich den gleichen Code verwendet, änderte ich das User-Modell, weil das Tutorial benutzt Mongoose und ich benutze Sequelize aber dieser Aspekt funktioniert gut, wenn ich klicke um mich mit FB anzumelden registriert mich oder mich anmeldet, die Abfragen machen die Arbeit.

Was jedoch nicht funktioniert, ist die Umleitung. Wenn ich mich über facebook registriere, bleibt es stecken und lädt nichts (Rad dreht sich weiter auf index.html (wo der FB-Button ist) und lädt nichts). Wenn ich Facebook-Login verwenden, zeigt es nur diese auf dem Bildschirm:

[object SequelizeInstance: user]

Auf dem Tutorial, der Lehrer EJS als Template-Sprache verwendet, aber schon I 95 gebaut % des Frontends des Projekts mit HTML, CSS und jQuery (ja, sollte React oder Angular verwendet haben, aber die Zeit ist empfindlich und war bereits Knoten lernen). Ich glaube, das ist einer der Gründe, warum das passiert, aber ich bin mir nicht 100% sicher, was hier vor sich geht und warum ich den Fehler bekomme oder wie ich mich herumkomme.

Jede Hilfe ist willkommen, wenn mehr Informationen/Code benötigt wird, lass es mich wissen. Danke

+0

ist dies der Code Ihrer App.js? – Nivesh

+0

hast du 'app.use (pass.initialize());' und 'app.use (pass.session());' auch gesetzt – Nivesh

+0

Das ist mein Server.js-Datei (nicht alles, nur der Pass Teil) und ja, ich habe beide – leofontes

Antwort

3

So nach einer guten Zeit Debugging und mit ein paar gute Hilfe, ich herausgefunden, was mein Problem verursacht, gab es eigentlich drei Fehler drin.

Vor allem in der Facebook-Strategie, das ist, wie ich es war gebaut soll:

passport.use(new FacebookStrategy({ 
    //Information stored on config/auth.js 
    clientID: configAuth.facebookAuth.clientID, 
    clientSecret: configAuth.facebookAuth.clientSecret, 
    callbackURL: configAuth.facebookAuth.callbackURL, 
    profileFields: ['id', 'emails', 'displayName', 'name', 'gender'] 

}, function (accessToken, refreshToken, profile, done) { 
    //Using next tick to take advantage of async properties 
    process.nextTick(function() { 
     db.user.findOne({ where : { idUser : profile.id } }).then(function (user, err) { 
      if(err) { 
       return done(err); 
      } 
      if(user) { 
       return done(null, user); 
      } else { 
       //Create the user 
       db.user.create({ 
        idUser : profile.id, 
        token : accessToken, 
        nameUser : profile.displayName, 
        email : profile.emails[0].value, 
        sex : profile.gender 
       }); 

       //Find the user (therefore checking if it was indeed created) and return it 
       db.user.findOne({ where : { idUser : profile.id } }).then(function (user, err) { 
        if(user) { 
         return done(null, user); 
        } else { 
         return done(err); 
        } 
       }); 
      } 
     }); 
    }); 
})); 

Der Rückruf nach db.user.findOne Parametern war eingeschaltet, so dass er gab mir einen Fehler jedes Mal, auch wenn es keine hatte, also habe ich diese geändert und auch eine Abfrage hinzugefügt, um nach dem Benutzer in der Datenbank zu suchen, nachdem er erstellt wurde, um ihn zurückgeben zu können.

Auf der zweiten facebook Route ist dies, wie ich es gebaut:

app.get('/auth/facebook/callback', 
    passport.authenticate('facebook', { failureRedirect: '/' }), 
    function(req, res) { 
     // Successful authentication, redirect home. 
     res.redirect('../../app.html'); 
    }); 

Das bin ich weiterhin gestattet mit HTML (Ich werde es wahrscheinlich umschreiben später eine bessere Sicht zu verwenden), und auf das Testen , Konnte ich die Informationen von req.user bekommen.

Schließlich hatte ich einen kleinen Namensfehler auf Passport serializeUser:

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

gerade von user.id zu user.idUser Änderung der Namenskonvention I verwendet zu halten.

Hoffentlich hilft dies anderen Leuten, Sequelize mit Passport zu benutzen.