在Go语言中验证Google登录ID令牌

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

Validating Google sign in ID token in Go

问题

我正在寻找一种在Android上使用Go后端服务器项目验证Google登录的ID令牌的方法。

在Go中,使用Google API Client Library进行ID令牌验证的等效函数是什么?

在这个页面上的"使用Google API Client Library"部分有Java和Python的示例,并提供了使用Google API Client Library验证ID令牌的PHP、Node.js和其他语言的链接。我查看了我的目标语言Go的相关信息,请参考这里:

https://github.com/google/google-api-go-client/blob/master/GettingStarted.md

然而,我发现在Go中没有像Java和Python示例中那样的等效函数来验证令牌。在Go中是否有类似的函数可以实现这样的功能?

我不想使用令牌信息端点

https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123

因为这会引入可能的延迟和网络错误。我希望使用Google API Client Library。请指导我应该查找哪些内容。

英文:

I am finding the way to validate ID token for Google sign-in for Android with a Go backend server project.

What is the equivalent function for validating ID tokens by using a Google API Client Library in Go?

From this page on Using a Google API Client Library section

https://developers.google.com/identity/sign-in/android/backend-auth#using-a-google-api-client-library

There are Java and Python examples and there are links for verify ID tokens with the Google API Client Library for PHP, Node.js, and other languages. I checked for my target language; Go here

https://github.com/google/google-api-go-client/blob/master/GettingStarted.md

However, I found not equivalent function for validating token like in Java and Python example. Is there any function in Go for doing such thing?

I don't want to use token info endpoint

https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123

since it introduces possible latency and network error. I wish to use Google API Client Library. Please guide me where should I look into.

答案1

得分: 33

这是翻译好的内容:

非常简单,只需要一行代码就可以解决。只需使用官方库:

go get google.golang.org/api/idtoken

然后编写以下代码:

payload, err := idtoken.Validate(context.Background(), tokenString, audience)
if err != nil {
    panic(err)
}
fmt.Print(payload.Claims)

然后你将得到以下输出:

map[
    aud:<你的网络应用客户端ID>
    azp:<你的安卓应用客户端ID>
    email:<经过身份验证的用户电子邮件> 
    email_verified:true
    exp:<到期时间>
    family_name:<经过身份验证的用户姓氏>
    given_name:<经过身份验证的用户名字>
    iat:<签发时间>
    iss: <accounts.google.com或https://accounts.google.com>
    locale:en
    name:<经过身份验证的用户全名>
    picture:<经过身份验证的用户照片URL>
    sub: <Google账户ID [用于唯一标识一个ID]>
]
英文:

It's very easy and has a one-liner solution. Just use the Official library:

go get google.golang.org/api/idtoken

and then write this code:

payload, err := idtoken.Validate(context.Background(), tokenString, audience)
if err != nil {
	panic(err)
}
fmt.Print(payload.Claims)

Then you will get this output:

map[
    aud:<Your web application client id>
    azp:<Your android application client id>
    email:<Authenticated user email> 
    email_verified:true
    exp:<expire at>
    family_name:<Authenticated user lastname>
    given_name:<Authenticated user firstname>
    iat:<issued at>
    iss: <accounts.google.com or https://accounts.google.com>
    locale:en
    name:<Authenticated User fullname>
    picture:<Authenticated User Photo URL>
    sub: <Google Account ID [Use this to identify a id uniquely]>
]

答案2

得分: 31

这是我使用https://github.com/google/google-api-go-client库完成的方法:

import (
	"google.golang.org/api/oauth2/v2"
	"net/http"
)

var httpClient = &http.Client{}

func verifyIdToken(idToken string) (*oauth2.Tokeninfo, error) {
	oauth2Service, err := oauth2.New(httpClient)
	tokenInfoCall := oauth2Service.Tokeninfo()
	tokenInfoCall.IdToken(idToken)
	tokenInfo, err := tokenInfoCall.Do()
	if err != nil {
		return nil, err
	}
	return tokenInfo, nil
}

oauth2.Tokeninfo对象包含有关用户的信息。
请注意,这会调用https://www.googleapis.com/oauth2/v2/tokeninfo,并且我认为所有Google API客户端库都会在内部进行此http调用。

英文:

This is how I've done it using https://github.com/google/google-api-go-client library:

import (
	"google.golang.org/api/oauth2/v2"
	"net/http"
)

var httpClient = &http.Client{}

func verifyIdToken(idToken string) (*oauth2.Tokeninfo, error) {
	oauth2Service, err := oauth2.New(httpClient)
	tokenInfoCall := oauth2Service.Tokeninfo()
	tokenInfoCall.IdToken(idToken)
	tokenInfo, err := tokenInfoCall.Do()
	if err != nil {
		return nil, err
	}
	return tokenInfo, nil
}

oauth2.Tokeninfo object has info about the user.
Note that this makes a call to https://www.googleapis.com/oauth2/v2/tokeninfo and I think that all Google API Client Libraries make this http call under the hood.

答案3

得分: 8

Google的idToken实际上是JWT格式,它是一种紧凑且自包含的带有签名的JSON。

参见:https://jwt.io/introduction/

google-auth-library-nodejs的OAuth2Client.prototype.verifyIdToken使用Google的公钥验证idtoken,并从idtoken中提取ClaimSet,而无需调用tokeninfo端点。

我刚刚从google-auth-library-nodejs中移植了verifyIdToken函数,并为此创建了一个库:https://github.com/futurenda/google-auth-id-token-verifier。

用法:

import (
     "github.com/futurenda/google-auth-id-token-verifier"
)

v := googleAuthIDTokenVerifier.Verifier{}
aud := "xxxxxx-yyyyyyy.apps.googleusercontent.com"
err := v.VerifyIDToken(TOKEN, []string{
    aud,
})
if err == nil {
    claimSet, err := googleAuthIDTokenVerifier.Decode(TOKEN)
    // claimSet.Iss,claimSet.Email ... (See claimset.go)
}
英文:

Google's idToken is actually in JWT format, which is compact and self-contained JSON with signature.

See also: https://jwt.io/introduction/

google-auth-library-nodejs's OAuth2Client.prototype.verifyIdToken verify the idtoken using Google's public key and extract ClaimSet from the idtoken without calling the tokeninfo endpoint.

I just ported the verifyIdToken function from google-auth-library-nodejs, and created a library for this: https://github.com/futurenda/google-auth-id-token-verifier.

Usage:

import (
     "github.com/futurenda/google-auth-id-token-verifier"
)

v := googleAuthIDTokenVerifier.Verifier{}
aud := "xxxxxx-yyyyyyy.apps.googleusercontent.com"
err := v.VerifyIDToken(TOKEN, []string{
    aud,
})
if err == nil {
    claimSet, err := googleAuthIDTokenVerifier.Decode(TOKEN)
    // claimSet.Iss,claimSet.Email ... (See claimset.go)
}

答案4

得分: 8

import (
    "google.golang.org/api/idtoken"
)

var token string           // 这个可能来自你的网页或移动应用
const googleClientId = ""  // 来自 Google 开发控制台的凭据

tokenValidator, err := idtoken.NewValidator(context.Background())
if err != nil {
    // 处理错误,停止执行
}

payload, err := tokenValidator.Validate(context.Background(), token, googleClientId)
if err != nil {
    // 处理错误,停止执行
}

email := payload.Claims["email"]
name  := payload.Claims["name"]
// 等等...

你可能需要向你的应用程序提供 Google 凭据:
https://cloud.google.com/docs/authentication/production

英文:
import (
	"google.golang.org/api/idtoken"
)

var token string           // this comes from your web or mobile app maybe
const googleClientId = ""  // from credentials in the Google dev console

tokenValidator, err := idtoken.NewValidator(context.Background())
if err != nil {
	// handle error, stop execution
}

payload, err := tokenValidator.Validate(context.Background(), token, googleClientId)
if err != nil {
	// handle error, stop execution
}

email := payload.Claims["email"]
name  := payload.Claims["name"]
// and so on...

You may need to provide your Google credentials to your application:
https://cloud.google.com/docs/authentication/production

huangapple
  • 本文由 发表于 2016年4月19日 18:47:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/36716117.html
匿名

发表评论

匿名网友

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

确定