Passport-Facebook authentication is not providing email for all Facebook accounts

前端 未结 7 925
忘了有多久
忘了有多久 2020-12-07 20:16

I am using Passport-Facebook authentication.

  passport.use(new FacebookStrategy({
            clientID: \'CLIENT_ID\',
            clientSecret: \'CLIENT_SECRET\         


        
相关标签:
7条回答
  • 2020-12-07 20:39

    When you are authenticating use something similar to this. You need to use add 'email' in the scope when you authenticate.

    app.get('/auth/facebook',
    passport.authenticate('facebook', { scope: ['email']}),
        function(req, res){
    });
    

    That has worked for me.

    Here were a few links that helped me out.

    https://github.com/jaredhanson/passport-facebook/issues/11 https://github.com/jaredhanson/passport-facebook#how-do-i-ask-a-user-for-additional-permissions

    0 讨论(0)
  • 2020-12-07 20:39

    Make sure you're providing the scope parameter into the first .authenticate() call, not the callback.

    Like this:

    router.get("/auth/facebook", passport.authenticate("facebook", {
        scope: [ "email" ], // scope goes here, not below
    }));
    
    router.get("/auth/facebook/callback",
        passport.authenticate("facebook", {
            successRedirect: "/",
            failureRedirect: "/login",
        }),
    );
    
    0 讨论(0)
  • 2020-12-07 20:47

    You can use the code provided as an example in the passport-facebook site as a starting point. Then, to get access to email, make sure to check @Forivin's answer.

    0 讨论(0)
  • 2020-12-07 20:47
    passport.use(new FacebookStrategy({
            clientID: 'CLIENT_ID',
            clientSecret: 'CLIENT_SECRET',
            callbackURL: "http://www.example.com/auth/facebook/callback"
        },
        function (accessToken, refreshToken, profile, done) {            
            process.nextTick(function () {                
               console.log(profile)
            });               
        }
    ));
    
    0 讨论(0)
  • 2020-12-07 20:50

    When passport doesn't return the profile.emails, profile.name.givenName, profile.name.familyName fields, or if they are missing, you can try to parse the https://graph.facebook.com/v3.2/ url, although you still need a token. You access the url, with of course a valid token, like:

    https://graph.facebook.com/v3.2/me?fields=id,name,email,first_name,last_name&access_token=

    It outputs a JSON response like:

    {
       "id": "5623154876271033",
       "name": "Kurt Van den Branden",
       "email": "kurt.vdb\u0040example.com",
       "first_name": "Kurt",
       "last_name": "Van den Branden"
    }
    

    Install the request module ($ npm install request --save), to be able to parse a JSON url and in your passport.js file:

    const request = require("request");
    
    passport.use(new FacebookStrategy({
            clientID        : 'CLIENT_ID',
            clientSecret    : 'CLIENT_SECRET',
            callbackURL     : "https://example.com/auth/facebook/callback"
        },
        function(req, token, profile, done) {
    
            let url = "https://graph.facebook.com/v3.2/me?" +
                      "fields=id,name,email,first_name,last_name&access_token=" + token;
    
            request({
                url: url,
                json: true
            }, function (err, response, body) {
                  let email = body.email;  // body.email contains your email
                  console.log(body); 
            });
        }
    ));
    

    You can add a lot of other parameters to the url, although some of them require user permission to return values. You can play with it on: https://developers.facebook.com/tools/explorer/

    0 讨论(0)
  • 2020-12-07 21:00

    Make sure these two things are in your code:

      passport.use(new FacebookStrategy({
                clientID: 'CLIENT_ID',
                clientSecret: 'CLIENT_SECRET',
                callbackURL: "http://www.example.com/auth/facebook/callback"
                passReqToCallback : true,
                profileFields: ['id', 'emails', 'name'] //This
            },
    

    and this:

    app.get('/connect/facebook', passport.authorize('facebook', { scope : ['email'] }));
    

    This gives you access to the following:

    • profile.id
    • profile.name.givenName
    • profile.name.familyName
    • profile.emails

    The last one being an array, so use profile.emails[0].value to get the first email address of the user.

    As shamim reza pointed out, you might want to check if profile.emails !== undefined because the property only exists if the user has at least one verified email address.

    As Weft pointed out, you might have to use the property email instead of emails.

    0 讨论(0)
提交回复
热议问题