简体   繁体   中英

Facebook authentication with passport. Cannot read property '0' of undefined error

I'm learning to add social authentication with Facebook to an app. Everything works fine, until I actually try to login to my test app with Facebook. Instead of being routed to the profile page, I get this error:

Cannot read property '0' of undefined

TypeError: Cannot read property '0' of undefined
    at Strategy.generateOrFindUser [as _verify] (C:\projects\Side            Projects\passyapp\app.js:16:19)
    at C:\projects\Side Projects\passyapp\node_modules\passport-  oauth2\lib\strategy.js:193:24
    at C:\projects\Side Projects\passyapp\node_modules\passport-  github\lib\strategy.js:174:7
    at passBackControl (C:\projects\Side Projects\passyapp\node_modules\oauth\lib\oauth2.js:134:9)
    at IncomingMessage.<anonymous> (C:\projects\Side Projects\passyapp\node_modules\oauth\lib\oauth2.js:157:7)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

BELOW IS A SNIPPET FROM MY APP.JS FILE:

function generateOrFindUser(accessToken, refreshToken, profile, done){
  if(profile.emails[0]) {
    User.findOneAndUpdate(
      { email: profile.emails[0] },
      {
        name: profile.displayName || profile.username,
        email: profile.emails[0].value,
        photo: profile.photos[0].value
      },
      {
        upsert: true
      },
    done
  );
  } else {
    var noEmailError = new Error("Your email privacy settings prevent you from signing in.");
    done(noEmailError, null);
  }
}

passport.use(new FacebookStrategy({
  clientID: process.env.FACEBOOK_APP_ID,
  clientSecret: process.env.FACEBOOK_APP_SECRET,
  callbackURL: "http://localhost:3000/auth/facebook/return",
  profileFields: ['email', 'id', 'displayName', 'photos']
},
  generateOrFindUser)
);


//in order for passport to handle sessions you need to implement the two methods
//directly below
passport.serializeUser(function(user, done) {
  done(null, user._id);
});

passport.deserializeUser(function(userId, done) {
  User.findById(userId, function(err, done) {
    //done(err, user);
  });
});

This is my User Schema

var UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
    trim: true,
    unique: true,
  },
  name: {
    type: String,
    required: true,
    trim: true,
  },
  favoriteBook: {
    type: String,
    required: false,
    trim: true
  },
  photo: {
    type: String,
    required: true,
    trim: true
  }
});

I hope this isn't a waste of your busy coder time. Any attempt to help is greatly appreciated.

EDIT: better answer

I'm guessing it's the profile.emails object (can't tell based on line number because your code is a snippet). Before that function you should have code that looks like this.

You need to ensure two things:

1. When you call passport.authenticate , make sure to request the email scope, like this: app.route('/auth/facebook').get(passport.authenticate('facebook', { scope: ['email']}));

2.

passport.use(new FacebookStrategy({
  clientID: facebookConfig.clientID,
  clientSecret: facebookConfig.clientSecret,
  callbackURL: facebookConfig.callbackURL,
  profileFields   : ['id', 'name', 'email'],
  },
  function generateOrFindUser...

It's important that your profileFields array contains email .

  1. Firstly, set your profileFields section.

     'facebookAuth' : { 'clientID' : 'your App ID', 'clientSecret' : 'your App Secret', 'callbackURL' : 'your Callback URL', 'profileFields' : ['emails'] }
  2. Now, we need to pull these details wherever we configure our passport code.

     passport.use(new FacebookStrategy({ // pull in our app id and secret from our auth.js file clientID : configAuth.facebookAuth.clientID, clientSecret : configAuth.facebookAuth.clientSecret, callbackURL : configAuth.facebookAuth.callbackURL, profileFields : configAuth.facebookAuth.profileFields }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM