Devendra Verma Devendra Verma - 3 months ago 24
Node.js Question

node js passport-facebook strategy authentication in sails

Hello I m trying to authenticate my app using facebook login. For this purpose I am using passport-facebook. My code is give below:

//config/passport.js
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var FACEBOOK_STRATEGY_CONFIG = {
clientID : 'xxxxxxxxxxxxxxxxxxxxx',
clientSecret : 'xxxxxxxxxxxxxxxxxxxxx',
callbackURL :'http://test.com:3000/auth/facebook/callback'
};
function onFacebookStrategyAuth(token, refreshToken, profile, done){

UserCredentials.findOne({'facebook.id' : profile.id}).then(user => {
if(user)
return done(null, user);
else{
var newUser = {};
newUser.facebook.id = profile.id;
newUser.facebook.token = token;
newUser.facebook.name = profile.name.givenName + ' ' + profile.name.familyName;
newUser.facebook.email = profile.emails[0].value;
return UserCredentials.create(newUser);
}
}).then(created => done(null,created)).catch(err => done(err, false));

}
passport.use(new FacebookStrategy(FACEBOOK_STRATEGY_CONFIG, onFacebookStrategyAuth));


my AuthController.js

//controllers/AuthController.js
var passport = require('passport');
module.exports = {
facebook : function(req,res){
passport.authenticate('facebook',{scope : 'email'})(req, res);
},

facebookCallback : function(req, res){
passport.authenticate('facebook',{
successRedirect : '/success',
failureRedirect : '/fail'
})(req, res);
}
};


Here is my config/route.js

module.exports.routes = {
'/auth/facebook': 'AuthController.facebook',
'/auth/facebook/callback': 'AuthController.facebookCallback',
'/success': {view : 'success'},
'/fail': {view : 'fail' }
}


When I click submit button and my my submit button action is defined as '/auth/facebook'. But I get the following error on console:

/node_modules/passport/lib/middleware/authenticate.js:343
next(err);
^
TypeError: next is not a function
at Strategy.strategy.error (/home/harsh/Desktop/cmbackend/node_modules/passport/lib/middleware/authenticate.js:343:9)
at /home/harsh/Desktop/cmbackend/node_modules/passport-oauth2/lib/strategy.js:166:34
at /home/harsh/Desktop/cmbackend/node_modules/oauth/lib/oauth2.js:177:18
at passBackControl (/home/harsh/Desktop/cmbackend/node_modules/oauth/lib/oauth2.js:123:9)
at IncomingMessage.<anonymous> (/home/harsh/Desktop/cmbackend/node_modules/oauth/lib/oauth2.js:143:7)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:441:9)
at process._tickDomainCallback (node.js:396:17)

Answer

The error is hinting you what is going on, passport fns are middleware, they expect to receive the next callback in (req, res, next) so you have two options here.

Assign the middleware directly to the controller action, like this:

var passport = require('passport');
module.exports = {
    facebook : passport.authenticate('facebook',{scope : 'email'}),

    facebookCallback :passport.authenticate('facebook',
      {successRedirect : '/success', failureRedirect : '/fail'}
    )
};

Or like this, in case you need to do something else on the action (Or just to be more clear on what's going on here)

var passport = require('passport');
module.exports = {
  facebook : function(req,res, next){
    // do something else here
    passport.authenticate('facebook',{scope : 'email'})(req, res, next);
  },

  facebookCallback : function(req, res){
    // You can do something else here
    passport.authenticate('facebook',{
      successRedirect : '/success',
      failureRedirect : '/fail'
    })(req, res, next);
  }
};

So to sum up, you need to pass next to the fn passport.authenticate returns

Comments