【问题标题】:Passport-Facebook authentication is not providing email for all Facebook accountsPassport-Facebook 身份验证未为所有 Facebook 帐户提供电子邮件
【发布时间】:2014-05-17 20:01:15
【问题描述】:

我正在使用Passport-Facebook 身份验证。

护照.使用(新FacebookStrategy({ clientID: 'CLIENT_ID', clientSecret: 'CLIENT_SECRET', 回调URL:“http://www.example.com/auth/facebook/callback” }, 函数(accessToken、refreshToken、profile、done){ process.nextTick(函数(){ 控制台日志(配置文件) }); } ));

对于某些 Facebook 帐户,我没有得到 email_id,我什至尝试使用如下范围变量,但仍然无法得到 email_id。

profileUrl : " " 和 ProfileFields : ['','']

【问题讨论】:

  • 并非每个 FB 帐户都设置了电子邮件地址……(人们也可以使用他们的手机号码注册 FB。)
  • 但我没有收到来自有电子邮件的帐户的电子邮件,要注册到 fb,我们需要有电子邮件 ID 对吗??
  • 我没有看到您在任何地方请求email 许可……您说您尝试使用范围,但是在哪里?不,正如我已经说过的,人们不必提供电子邮件地址来注册 FB。
  • 确保在此处登录accessToken 并尝试使用Graph API Explorer。确保左侧的“电子邮件”权限未灰显。如果是,则您没有在正确的时间要求范围。请参阅 passport-facebook 项目中的this comment
  • stackoverflow.com/questions/21775198/… 这解决了我的问题。试试这个。

标签: javascript node.js passport.js passport-facebook


【解决方案1】:

确保这两件事在您的代码中:

  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
        },

还有这个:

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

这使您可以访问以下内容:

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

最后一个是数组,所以使用profile.emails[0].value来获取用户的第一个电子邮件地址。

正如shamim reza 指出的那样,您可能需要检查profile.emails !== undefined 是否存在,因为该属性仅在用户至少有一个经过验证的电子邮件地址时才存在。

正如Weft 指出的那样,您可能必须使用属性email 而不是emails

【讨论】:

  • meanjs 样板缺少 profileFields 行
  • 哇,你拯救了我的一天。每个人都在谈论范围,但没有人谈论 profileFields
  • 给他“最佳答案” :)
  • 确实需要“profileFields”字段。此外,我不需要 passReqToCallback。我在passport-facebook中搜索了它,但它不存在(我猜它没有被使用,所以你可能会忽略它)。
  • @ArslArsl 如果未验证登录用户电子邮件,则 facebook 不会发送电子邮件字段
【解决方案2】:

当您进行身份验证时,请使用与此类似的内容。您需要在验证时在范围内使用添加“电子邮件”。

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

这对我有用。

这里有一些对我有帮助的链接。

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

【讨论】:

  • 确保在设置策略时包含“profileFields”字段。仅在此处添加“范围”不会起作用(至少对我而言没有)。有关更多信息,请查看其他答案:stackoverflow.com/a/32370813/1814970
  • 我收到了一些用户的电子邮件,但没有一些用户的电子邮件?有什么原因吗?
  • @SandipSubedi 似乎下面的 vinesh 回答了这个问题
【解决方案3】:

我想在这里添加更多信息。

在创建 FacebookStrategy 和 passport.authorize('facebook', { scope : ['email'] }) 时添加 profileFields: ['emails'] 可以解决大多数用户的问题。

还有其他可能的原因导致您在验证后收不到用户的电子邮件。

  • 帐户中没有电子邮件地址
  • 帐户中没有确认的电子邮件地址
  • 帐户中没有经过验证的电子邮件地址
  • 用户输入了一个安全检查点,要求他们重新确认 他们的电子邮件地址,他们还没有这样做
  • 用户的电子邮件地址无法访问

​ 您需要确保您的用户没有上面列出的任何问题。更多信息可以找到https://developers.facebook.com/bugs/1802930019968631/

【讨论】:

    【解决方案4】:

    当护照没有返回profile.emails, profile.name.givenName, profile.name.familyName 字段时,或者如果它们丢失,您可以尝试解析https://graph.facebook.com/v3.2/ url,尽管您仍然需要一个令牌。您当然可以使用有效的令牌访问 url,例如:

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

    它输出如下 JSON 响应:

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

    安装请求模块 ($ npm install request --save),以便能够解析 JSON url 并在您的 passport.js 文件中:

    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); 
            });
        }
    ));
    

    您可以向 url 添加许多其他参数,尽管其中一些需要用户权限才能返回值。你可以在上面玩:https://developers.facebook.com/tools/explorer/

    【讨论】:

      【解决方案5】:

      确保您将范围参数提供给第一个 .authenticate() 调用,而不是回调。

      像这样:

      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",
          }),
      );
      

      【讨论】:

        【解决方案6】:

        您可以使用code provided as an example in the passport-facebook site 作为起点。然后,要访问电子邮件,请务必查看@Forivin's answer

        【讨论】:

          【解决方案7】:
          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)
                  });               
              }
          ));
          

          【讨论】:

            猜你喜欢
            • 2016-11-12
            • 2017-07-03
            • 1970-01-01
            • 2015-03-16
            • 2015-03-21
            • 1970-01-01
            • 2023-03-22
            • 2016-09-28
            • 2018-10-15
            相关资源
            最近更新 更多