【问题标题】:Google oauth2 endpoint does not return user profile info (name etc)Google oauth2 端点不返回用户个人资料信息(名称等)
【发布时间】:2019-06-11 07:45:17
【问题描述】:

我正在尝试在我的网络服务 (golang) 上使用 google oauth2,但无法获取用户个人资料信息(名字、姓氏)。

我正在尝试各种端点,但每次都得到这样的答案:

{
    "id":"*************",
    "email":"***@gmail.com",
    "verified_email":true,
    "picture":"https://***/photo.jpg"
}

同时具有这组范围的谷歌游乐场返回这种答案:

{
  "family_name": "***", 
  "name": "****", 
  "picture": "https://*******/photo.jpg", 
  "locale": "ru", 
  "email": "****@gmail.com", 
  "given_name": "*****", 
  "id": "************", 
  "verified_email": true
}

如何在我的网络应用程序中获得相同的答案? 本网站和互联网上的人们建议添加配置文件范围,但我已经这样做了。

这是我的代码(缩短)

"golang.org/x/oauth2"
"golang.org/x/oauth2/google"

func init() {
    googleOauthConfig = &oauth2.Config{
        RedirectURL:  "*******",
        ClientID:     "*********",
        ClientSecret: "******",
        Scopes: []string{
            "https://www.googleapis.com/auth/userinfo.email",
            "https://www.googleapis.com/auth/userinfo.profile",
            "openid"},
        Endpoint: google.Endpoint,
    }
}

var googleOauthConfig *oauth2.Config

//const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v1/userinfo"
const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v2/userinfo"
//const oauthGoogleURLAPI = "https://www.googleapis.com/oauth2/v3/userinfo"
const oauthGoogleURLAPI2 = "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses"
//const oauthGoogleURLAPI = "https://openidconnect.googleapis.com/v1/userinfo"

func HandleGoogleCallback(w http.ResponseWriter, r *http.Request) {
    ...

    oauthState, _ := r.Cookie(oauthstateCookieName)

    code := r.FormValue("code") 

    gtoken, err := googleOauthConfig.Exchange(oauth2.NoContext, code)

    bearer := "Bearer " + gtoken.AccessToken

    req, err := http.NewRequest("GET", oauthGoogleURLAPI, nil)
    req.Header.Add("Authorization", bearer)

    gresponse, err := http.DefaultClient.Do(req)

    contents, err := ioutil.ReadAll(gresponse.Body)

    authContent := &AuthContent{}

    err = json.Unmarshal(contents, authContent)

    log.Println(authContent)

    ...
}

我也看过这篇文章Google Oauth2 userinfo API not returning user's name data 但结果是一样的:没有个人资料信息。

谢谢。

更新: 根据评论的建议,我稍微更正了“golang.org/x/oauth2”的代码并获得了 id_token。 当我在 jwt.io 上检查这个 id 令牌时,我看到了我需要的所有数据。 但我认为应该通过这样的 API 请求检索个人资料信息

req, err := http.NewRequest("GET", <endPoint>, nil)
gresponse, err := http.DefaultClient.Do(req)

在这个例子中,只使用了标准的 go 库,并且 gresponse 包含整个 http 响应,不是吗?为什么响应不包含我需要的字段?

【问题讨论】:

  • 尝试获取 id 令牌并将其放入 jwt.io。 Gtoken 也应该包含一个 id 令牌。我想知道您的库是否只是没有正确解析响应。
  • 看来你是对的。当我从库的深处提取 id_token 并通过 jwt.io 进行检查时,我看到了我需要的所有数据。但我不明白出了什么问题。我认为应该通过像req, err := http.NewRequest("GET", &lt;endPoint&gt;, nil) gresponse, err := http.DefaultClient.Do(req) 这样的API 请求来检索个人资料信息。在这个例子中,只使用了标准的 go 库,gresponse 包含整个 http 响应,不是吗?为什么响应不包含我需要的字段?

标签: go oauth-2.0 google-oauth userinfo


【解决方案1】:
  1. 处理googleOauthConfig.Exchange(oauth2.NoContext, code) 中的错误
  2. 处理http.DefaultClient.Do 中的错误
  3. 处理ioutil.ReadAll(gresponse.Body) 中的错误
  4. 处理json.Unmarshal 中的错误

你可能会找到答案。

我还记得我一直发送 access_token 作为查询参数:

response, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken)

【讨论】:

  • 感谢您的回答。在原始代码(未缩短)中,我正在检查所有返回的错误,例如 if err != nil { log.Println("Code exchange failed: " + err.Error()) json.NewEncoder(w).Encode(response) return } 但没有任何错误。我也尝试使用参数而不是标题发送查询,但结果是一样的。
【解决方案2】:

我找到了答案。那是我的错。 接收结果的结构是这样的

type AuthContent struct {
    ID            string `json:"id"`
    Email         string `json:"email"`
    VerifiedEmail bool   `json:"verified_email"`
    Picture       string `json:"picture"`
}

这就是为什么响应中没有像 name 这样的字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多