英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论