使用服务帐户验证对Golang中云函数的客户端调用

使用服务帐户验证对Golang中云函数的客户端调用,go,google-cloud-functions,google-oauth,Go,Google Cloud Functions,Google Oauth,我将自己的云功能部署到GCP。在云功能中,我启用了使用Google服务帐户进行身份验证。我需要编写一个Golang代码来调用这个云函数。我对Nodejs也有同样的目的,但不能让Golang工作 这是我的Nodejs代码(工作): const{GoogleAuth}=require('google-auth-library'); const targetAudience=“云函数url” 异步函数run(){ const auth=new GoogleAuth(); const client=wa

我将自己的云功能部署到GCP。在云功能中,我启用了使用Google服务帐户进行身份验证。我需要编写一个Golang代码来调用这个云函数。我对Nodejs也有同样的目的,但不能让Golang工作

这是我的Nodejs代码(工作):

const{GoogleAuth}=require('google-auth-library');
const targetAudience=“云函数url”
异步函数run(){
const auth=new GoogleAuth();
const client=wait auth.getIdTokenClient(targetAudience);
const res=wait client.request({url});
控制台信息(资源数据);
}
我的Golang代码:

导入“golang.org/x/oauth2/google”
func getToken()(错误){
范围:=”https://www.googleapis.com/auth/cloud-platform"
client,err:=google.DefaultClient(context.Background(),scope)
如果错误!=零{
回来
}
res,err:=client.Get(“云函数url”)
如果错误!=零{
回来
}
fmt.Println(res)
回来
}
我还尝试自定义代码以添加
targetAudience
,但它也不起作用

baseUrl:=“您的云函数baseUrl”
ctx:=context.Background()
targetAudience:=baseUrl
凭据,错误:=google.FindDefaultCredentials(ctx)
如果出错!=零{
fmt.Printf(“无法获取凭据:%v”,错误)
操作系统退出(1)
}
tokenSrc,err:=google.JWTAccessTokenSourceFromJSON(credentials.JSON,targetAudience)
如果出错!=零{
fmt.Printf(“无法创建jwt源:%v”,错误)
操作系统退出(1)
}
客户端:=oauth2.NewClient(context.Background(),tokenSrc)
如果出错!=零{
回来
}
res,err:=client.Get(baseUrl+“子url”)
如果出错!=零{
回来
}

我已经检查并确保我的服务帐户已正确加载。在上述两种情况下,我都收到了
401“无法验证访问令牌”

我编写了一个名为的开源应用程序。它在Go中,我生成签名身份令牌,以便能够调用私有云运行和云函数


您可以随意使用它或复制自己应用程序所需的核心代码!!如果您愿意,我们可以在这里讨论或在GitHub上打开一个问题。

在深入研究和之后,我发现Golang中的库没有完全遵循google的OAuth2协议

  • Google规范中的流程:在HTTP客户端中生成JWT并对其签名(使用服务帐户)--->发送到Google服务器-->获取新的签名JWT-->将新令牌用于其他请求
  • Golang lib:生成并签署JWT-->将此令牌用于其他请求
令人惊讶的是,Nodejs库能够正确处理流,而Golang库却不能。我把我的调查总结成一个例子

对于那些想要简短回答的人,以下是我的实现(我将一些部分转移到公共回购协议中):

导入(
“上下文”
“fmt”
“io/ioutil”
“操作系统”
“github.com/CodeLinkIO/go cloudfunction auth/cloudfunction”
“golang.org/x/oauth2/google”
)
func main(){
baseUrl:=“您的cloudfunction baseUrl”
ctx:=context.Background()
targetAudience:=baseUrl
凭据,错误:=google.FindDefaultCredentials(ctx)
如果错误!=零{
fmt.Printf(“无法获取凭据:%v”,错误)
操作系统退出(1)
}
jwtSource,err:=cloudfunction.JWTAccessTokenSourceFromJSON(credentials.JSON,targetAudience)
如果错误!=零{
fmt.Printf(“无法创建jwt源:%v”,错误)
操作系统退出(1)
}
client:=cloudfunction.NewClient(jwtSource)
res,err:=client.Get(baseUrl+“/cloudfunction子页”)
如果错误!=零{
fmt.Printf(“无法获取结果:%v”,错误)
操作系统退出(1)
}
延迟res.Body.Close()
body,err:=ioutil.ReadAll(res.body)
如果错误!=零{
fmt.Printf(“无法读取响应:%v”,错误)
操作系统退出(1)
}
println(字符串(正文))
}

调用
google.DefaultClient
client.Get
返回的错误有哪些?google.DefaultClient没有返回错误(我检查了我的服务帐户是否正确加载)。对于
客户端.Get
,它返回401“无法验证访问令牌”