在Golang中获取Google云服务账号的访问令牌?

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

Get access token for a google cloud service account in Golang?

问题

我正在使用谷歌云的服务帐号。由于某种原因,我想以编程方式在golang中获取访问令牌。我可以在命令行上执行gcloud auth application-default print-access-token

谷歌提供了一个库(https://pkg.go.dev/golang.org/x/oauth2@v0.0.0-20220309155454-6242fa91716a/google?utm_source=gopls),看起来可以让我获取令牌。以下是我尝试使用它的方式:

	credentials, err := auth.FindDefaultCredentials(ctx)
	if err == nil {
		glog.Infof("found default credentials. %v", credentials)
		token, err2 := credentials.TokenSource.Token()
		fmt.Printf("token: %v, err: %v", token, err2)
		if err2 != nil {
		    return nil, err2
		}

然而,我收到一个错误,错误信息为token: <nil>, err: oauth2: cannot fetch token: 400 Bad Request

我已经定义了GOOGLE_APPLICATION_CREDENTIALS环境变量,并将其指向了JSON文件。

英文:

I'm using a service account on google cloud. For some reason, I want to get the access token programmatically in golang. I can do gcloud auth application-default print-access-token on the command line.

There is a library by google that seems to allow me to get the token. Here is how I try to use it:

	credentials, err := auth.FindDefaultCredentials(ctx)
	if err == nil {
		glog.Infof(&quot;found default credentials. %v&quot;, credentials)
		token, err2 := credentials.TokenSource.Token()
		fmt.Printf(&quot;token: %v, err: %v&quot;, token, err2)
		if err2 != nil {
		    return nil, err2
		}

However, I get an error saying token: &lt;nil&gt;, err: oauth2: cannot fetch token: 400 Bad Request.

I already have GOOGLE_APPLICATION_CREDENTIALS env variable defined and pointing to the json file.

答案1

得分: 6

运行您的代码原样返回一个错误:

提供了无效的 OAuth 范围或 ID 令牌受众

我从Google 的 OAuth 范围中添加了一个通用的 Cloud Platform 可写范围:

https://www.googleapis.com/auth/cloud-platform

这样做似乎有效。请参见下面的代码:

package main

import (
	"context"
	"log"

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

func main() {
	var token *oauth2.Token
	ctx := context.Background()
	scopes := []string{
		"https://www.googleapis.com/auth/cloud-platform",
	}
	credentials, err := auth.FindDefaultCredentials(ctx, scopes...)
	if err == nil {
		log.Printf("found default credentials. %v", credentials)
		token, err = credentials.TokenSource.Token()
		log.Printf("token: %v, err: %v", token, err)
		if err != nil {
			log.Print(err)
		}
	}
}

最近我在使用这个库时遇到了一些挑战(访问需要 JWT 受众的 Cloud Run 服务)。在朋友的推荐下,我改用了 google.golang.org/api/idtoken。这个 API 非常相似。

英文:

Running your code as-is, returns an err:

Invalid OAuth scope or ID token audience provided

I added the catch-all Cloud Platform writable scope from Google's OAuth scopes:

https://www.googleapis.com/auth/cloud-platform

Doing so, appears to work. See below:

package main

import (
	&quot;context&quot;
	&quot;log&quot;

	&quot;golang.org/x/oauth2&quot;
	auth &quot;golang.org/x/oauth2/google&quot;
)

func main() {
	var token *oauth2.Token
	ctx := context.Background()
	scopes := []string{
		&quot;https://www.googleapis.com/auth/cloud-platform&quot;,
	}
	credentials, err := auth.FindDefaultCredentials(ctx, scopes...)
	if err == nil {
		log.Printf(&quot;found default credentials. %v&quot;, credentials)
		token, err = credentials.TokenSource.Token()
		log.Printf(&quot;token: %v, err: %v&quot;, token, err)
		if err != nil {
			log.Print(err)
		}
	}
}

I had some challenges using this library recently (to access Cloud Run services which require a JWT audience). On a friend's recommendation, I used google.golang.org/api/idtoken instead. The API is very similar.

huangapple
  • 本文由 发表于 2022年5月17日 21:55:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/72275338.html
匿名

发表评论

匿名网友

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

确定