Validating Google sign in ID token in Go
Solution 1
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.
Solution 2
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(), request.IdToken, "your google client id")
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]>
]
Solution 3
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)
}
Solution 4
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
Comments
-
ともこ about 2 years
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
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.
-
ともこ about 8 yearsIt seems like we need to call oauth2/v3 not /v2 and if we still need to call to that url, how would it avoid the latency and network problem?
-
AlexCV about 8 yearsgoogle-api-go-client doesn't have oauth2/v3, but v2 works well. I don't know if you can avoid the http call.
-
Etienne Marais almost 4 years
oauth2.New(httpClient)
seems like it's marked as deprecated in favour ofoauth2.NewService(ctx, ClientOption)
-
Anton over 3 yearsBefore creating NewValidator, it expects that GOOGLE_APPLICATION_CREDENTIALS env variable is set to the json file downloaded from the console. Otherwise, idtoken.NewValidator fails as it expects some credentials. I can't get it to work with idtoken.Validate. I get this error: Get "googleapis.com/oauth2/v3/certs": private key should be a PEM or plain PKCS1 or PKCS8; parse error: asn1: syntax error: sequence truncated. Any idea?
-
Gooz over 3 yearsThis issue suggests that you should actually use the idtoken package instead.
-
Asad-ullah Khan about 3 yearsI believe this is the new correct answer. A little confusing that idtoken is a subpackage of oauth2 in other langs like Python, but in Go its a separate lib