NodeJS护照Facebook OAuth

我一直在学习NodeJS的课程和教程,并决定在一个应用程序中使用它们。

对于这个项目,我需要用户注册并login才能将其活动存储在数据库中。 我使用Passport来做这个过程,这个项目的这个部分的代码是这样的:

/****** 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('/'); } } 

我使用Passport在Facebook Auth上使用的教程使用了几乎相同的代码,我更改了User模型,因为教程使用了Mongoose,而且我使用了Sequelize,但是这方面的工作很好,当我点击注册FB时,logging我,查询做的工作。

但是,不工作的是redirect。 当我注册使用Facebook时,它卡住,不加载任何东西(轮子在index.html(FBbutton所在的地方)不停地旋转,不加载任何东西)。 当我使用Facebooklogin时,它只显示在屏幕上:

[对象SequelizeInstance:用户]

在教程中,教师使用EJS作为模板语言,但是我已经使用HTML,CSS和jQuery构build了项目前端的95%(是的,应该使用了React或者Angular,但是时间很敏感,并且已经在学习Node )。 我相信这是发生这种情况的原因之一,但我不能100%确定这里发生了什么事情,为什么我会得到错误或如何解决。

任何帮助表示赞赏,如果需要更多信息/代码,请告诉我。 谢谢

所以经过很长时间的debugging和一些很好的帮助之后,我发现是什么原因导致了我的问题,其中有三个错误。

首先,在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 (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); } }); } }); }); })); 

db.user.findOne之后的callback已经切换了参数,所以它每次都给我一个错误,即使它没有,所以我切换了它们,并在创build它之后添加了一个查询来查找数据库中的用户能够返回它。

在第二个Facebook路线,这是我如何build立它:

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

这使我可以继续使用HTML(我稍后可能会重写它以使用更好的视图),在testing中,我可以从req.user中获取信息。

最后,我在Passport的serializeUser上有一个小的命名错误:

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

只是从user.id更改为user.idUser来维护我使用的命名约定。

希望这可以帮助其他人使用Passport和Sequelize。