Golang谷歌客户端API,如何使用`Userinfo`结构获取用户信息

huangapple go评论98阅读模式
英文:

Golang google client api, how to get the user information with `Userinfo` struct

问题

我目前正在使用Golang构建一个后端Rest API,用于处理来自移动应用程序的HTTP请求。我正在实现的一个功能是通过外部提供商(例如Google、Apple等)进行注册/登录。

对于Google,我阅读了这篇文章,了解如何与后端服务器进行身份验证。主要思路是通过POST端点将令牌ID发送到后端,并验证令牌的内容。一旦验证了令牌,我就可以从后端检索用户信息并创建一个帐户(如果不存在)。

到目前为止,使用oath2 Golang包,我可以这样验证令牌:

func verifyIdToken(idToken string) error {
    ctx := context.Background()
    oauth2Service, err := oauth2.NewService(ctx, option.WithoutAuthentication())

    if err != nil {
        return err
    }

    tokenInfoCall := oauth2Service.Tokeninfo()
    tokenInfoCall.IdToken(idToken)

    tokenInfo, err := tokenInfoCall.Do()

    if err != nil {
        e, _ := err.(*googleapi.Error)
        return e
    }
    fmt.Println(tokenInfo.Email)
    return nil
}

请注意:为了获取令牌ID,我正在使用Oauth playground,并设置了以下范围:

https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
opened

在搜索oauth2后,我注意到了一个包含我所需信息的UserInfo类型。然而,tokenInfo对象并没有返回用户的所有信息,比如名字和姓氏。但是,我在如何获取UserInfo方面遇到了一些困难。

简而言之,我创建了一个名为getUserInfo的函数,如下所示:

func getUserInfo(service *oauth2.Service) (*oauth2.Userinfo, error) {
    userInfoService := oauth2.NewUserinfoV2MeService(service)

    userInfo, err := userInfoService.Get().Do()

    if err != nil {
        e, _ := err.(*googleapi.Error)
        fmt.Println(e.Message)
        return nil, e
    }
    return userInfo, nil
}

注意:我在verifyIdToken中调用了getUserInfo
userInfo, err := getUserInfo(oauth2Service)

然而,我始终收到401错误:

googleapi: Error 401: Request is missing required authentication credential. 
Expected OAuth 2 access token, login cookie or other valid authentication credential. 
See https://developers.google.com/identity/sign-in/web/devconsole-project., 
unauthorized

因此,我不确定该怎么办。

英文:

I am currently building a backend Rest API with Golang to handle HTTP requests from a mobile application. One of the features that I am now implementing is a signup/login by using an external provider, e.g., Google, Apple, etc.

For Google, I've read this article on how to authenticate with a backend server. The main idea is to send a token id to the backend via a POST endpoint and validate the content of the Token. Once the Token is validated, I can retrieve the user information from the backend and create an account (if it does not exist).

So far, with the oath2 Golang package, I can validate the Token like so:

func verifyIdToken(idToken string) error {
	ctx := context.Background()
	oauth2Service, err := oauth2.NewService(ctx, option.WithoutAuthentication())

	if err != nil {
		return err
	}

	tokenInfoCall := oauth2Service.Tokeninfo()
	tokenInfoCall.IdToken(idToken)

	tokenInfo, err := tokenInfoCall.Do()

	if err != nil {
		e, _ := err.(*googleapi.Error)
		return e
	}
	fmt.Println(tokenInfo.Email)
	return nil
}

PLEASE NOTE: To obtain the token Id, I am using the Oauth playground, and I set these scopes:

https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
opened

After searching on oauth2, I noticed a type UserInfo containing all the info I need. However, the tokenInfo object does not return all the information from the user, such as first name and last name. But, I'm having some difficulty on how to get UserInfo.

In short, I created a function called getUserInfo like so:

func getUserInfo(service *oauth2.Service) (*oauth2.Userinfo, error) {
	userInfoService := oauth2.NewUserinfoV2MeService(service)

	userInfo, err := userInfoService.Get().Do()

	if err != nil {
		e, _ := err.(*googleapi.Error)
		fmt.Println(e.Message)
		return nil, e
	}
	return userInfo, nil
}

NOTE: I called the getUserInfo within the verifyIdToken
userInfo, err := getUserInfo(oauth2Service)

However, I'm always getting this 401 error:

googleapi: Error 401: Request is missing required authentication credential. 
Expected OAuth 2 access token, login cookie or other valid authentication credential. 
See https://developers.google.com/identity/sign-in/web/devconsole-project., 
unauthorized

With that, I'm not sure what to do.

答案1

得分: 1

我认为你很久以前就找到了你问题的答案,但我还是在这里留下我的解决方案。

UserinfoService 实际上并没有传递一个令牌。要做到这一点,你可以使用以下代码:

import "google.golang.org/api/googleapi"
    token := "ya29.a0Aa4xrXMAp..."
    userInfo, err := userInfoService.Get().Do(googleapi.QueryParameter("access_token", token))
    if err != nil {
        e, _ := err.(*googleapi.Error)
        fmt.Println(e.Message)
        return nil, e
    }
英文:

I think you have found the answer to your question for a long time, but I still leave my solution here.

The UserinfoService doesn't actually pass a token inside. To do this, you can use code like this:

import 	"google.golang.org/api/googleapi"
    token := "ya29.a0Aa4xrXMAp..." 
    userInfo, err := userInfoService.Get().Do(googleapi.QueryParameter("access_token", token))
    if err != nil {
        e, _ := err.(*googleapi.Error)
        fmt.Println(e.Message)
        return nil, e
    }

huangapple
  • 本文由 发表于 2021年12月28日 23:22:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/70509066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定