Github 用户电子邮件为空,尽管 user:email 范围

Github user email is null, despite user:email scope

我正在关注 Github’s OAuth flow, and obtaining an access token that gives me access to the user’s email scope. When I exchange a code for an access token, using the https://github.com/login/oauth/access_token 端点,我收到以下响应:

{
  access_token: '83f42..xxx’,
  token_type: 'bearer',
  scope: 'user:email' 
}

看起来很棒。所以我提出这个请求,使用令牌来获取我的用户数据:

Accept-Language: en-us
Accept: application/json
Authorization: token 83f42..xxx
Accept-Encoding: gzip, deflate

GET https://api.github.com/user

我确实收到了我的用户对象作为响应,但电子邮件 属性 为空。还有其他人遇到这个问题吗?

我找到了发生这种情况的原因以及解决方法。根据 docs:

Note: The returned email is the user's publicly visible email address (or null if the user has not specified a public email address in their profile).

在您的 GitHub 个人资料设置中,在 Public 电子邮件 下,一些用户(包括我自己)将该选项设置为 "Don't show my email address."仅 returns 调用 /user public 电子邮件地址,因此如果用户不希望显示它,API 将尊重它。

要获取用户的电子邮件地址,无论他们是否是 public,请使用对 /user/emails 的调用。您将以与 /user 请求完全相同的方式使用访问令牌:

Accept-Language: en-us
Accept: application/json
Authorization: token 83f42..xxx
Accept-Encoding: gzip, deflate

GET https://api.github.com/user/emails

这个电话给了我以下 JSON 回复:

[
  {
    "email": "user@example.com",
    "primary": true,
    "verified": true
  }
]

无法将其放入评论中,因此回答 node.js passport-github 案例:

var GitHubStrategy = require('passport-github').Strategy;

passport.use('github-login', new GitHubStrategy({
  clientID: config.clientId,
  clientSecret:  config.secret,
  callbackURL: config.host + config.callback,
  passReqToCallback: true, // req object on auth is passed as first arg
  scope: [ 'user:email' ], // fetches non-public emails as well
},
  function (req, accessToken, refreshToken, profile, done) {
    // find user by profile and update it
    // or create the user object given the req, tokens and profile objs
    // don't forget to call `done(null, user)` once done
}
));

您需要使用访问令牌向 https://api.github.com/user/emails 发出额外请求。

这是完整的身份验证流程:

  1. 要获取“代码”,首先将用户重定向到 https://github.com/login/oauth/authorize?client_id={CLIENTID}&redirect_uri={REDIRECT_URL}&scope=read:user,user:email

  2. 然后要获取访问令牌,请使用您收到的“代码”发出 POST 请求,如下所示: https://github.com/login/oauth/access_token?client_id={clientID}&client_secret={clientSecret}&code={code}

  3. 现在当您收到访问令牌时,首先向 /user 端点发出请求,然后向 /user/emails 端点发出请求。确保使用参数 Authorization: "token {accessToken}"

    在 header 中传递访问令牌

要获取基本用户数据,请对此 url 发出 GET 请求: https://api.github.com/user

然后要获取用户电子邮件,请向 https://api.github.com/user/emails

发出 GET 请求

您可能会在结果中收到多封电子邮件。结果将如下所示:

[
  {
    email: 'johndoe100@gmail.com',
    primary: true,
    verified: true,
    visibility: 'public'
  },
  {
    email: 'johndoe111@domain.com',
    primary: false,
    verified: true,
    visibility: null
  }
]

您可以 select 将 primary 参数设置为 true