使用Go验证远程配置REST API的服务帐户



在这里,Firebase文档解释了如何检索请求远程配置Rest API所需的令牌

它提供了Python、Java和Node.js的示例代码。因为没有Go的代码,所以将我发送到Google客户端库(用于Go(。你也许能理解为什么我在那里迷路了。。。

这些例子在Java中使用GoogleCredential,在Python使用ServiceAccountCredentials和在Node.jsgoogle.auth.JWT。我在这里找不到任何一个。我不知道为什么没有明确的命名约定。

我发现

firebaseremoteconfig-gen.go:代码看起来已经实现了Firebase文档页面试图实现的";手动">。比较:单据,包装。

帮助

因为";使用示例";的包装结束奇怪的突然和广泛的相反,我不明白如何利用它。

如果有人能告诉我如何使用,我会得到帮助

firebaseremoteconfigService, err := firebaseremoteconfig.New(oauthHttpClient)

我不知道从哪里得到oauthHttpClient。存储库中有一个oauth2包,但我面临着同样的问题:

oauth2Service, err := oauth2.New(oauthHttpClient)

我又需要oauthHttpClient,所以这不可能是一个解决方案
http.Client可以是任何内容,但我需要使用service-account.json文件进行身份验证,如这里的三个示例片段所示。

标记说明

我希望有人有经验集成Firebase RemoteConfigGo,有人知道Google Client API身份验证的工作原理,或者有人足够擅长Go以了解使用情况。

使用谷歌API进行身份验证有两种主要方法,它们在这里有文档记录:

链接到文档

记录的方法是"3级OAuth"、"使用API密钥",最后是"服务帐户"。

从你在问题中包含的链接;您正在查看"服务帐户"的Python/Java/Node示例。

在go中使用服务帐户

您所指的oauthHttpClient是一个http客户端,它将自动将身份验证信息附加到请求中。

你可以使用这个包创建一个:

https://godoc.org/golang.org/x/oauth2/google

以其他语言链接的示例使用"服务帐户json密钥文件"。

使用下面链接的方法,您可以读取该密钥文件并创建一个jwt.Config结构,该结构将允许您访问所需的客户端。

https://godoc.org/golang.org/x/oauth2/google#JWTConfigFromJSON

链接的其他语言示例的go等价物是;

data, err := ioutil.ReadFile("/path/to/your-project-key.json")
if err != nil {
log.Fatal(err)
}
conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/firebase.remoteconfig")
if err != nil {
log.Fatal(err)
}
// Initiate an http.Client. The following GET request will be
// authorized and authenticated on the behalf of
// your service account.
client := conf.Client(oauth2.NoContext)
client.Get("...")

我刚刚开始使用同一个库(来自AppEngine Standard项目(。这就是我创建服务客户端的方式:

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"golang.org/x/oauth2/google"
fb "google.golang.org/api/firebaseremoteconfig/v1"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
)
const (
// Name of our service account file
saFileName = "my-firebase-sa.json"
// OAuth scopes used for remote config API
scopeRemoteConfig = "https://www.googleapis.com/auth/firebase.remoteconfig"
)
func createFirebaseService(ctx context.Context) (*fb.Service, error) {
data, err := ioutil.ReadFile(saFileName)
if err != nil {
return nil, err
}
conf, err := google.JWTConfigFromJSON(data, scopeRemoteConfig)
if err != nil {
return nil, err
}
return fb.New(conf.Client(ctx))
}

我这样称呼它:

func fetchConfig(ctx context.Context) (*fb.RemoteConfig, error) {
s, err := createFirebaseService(ctx)
if err != nil {
log.Errorf(ctx, "Failed to create firebase service: %v", err)
return nil, fmt.Errorf("Failed to initialize Firebase service")
}
projectID := "projects/" + appengine.AppID(ctx)
cfg, err := s.Projects.GetRemoteConfig(projectID).Do()
if err != nil {
log.Errorf(ctx, "Failed to call Firebase remote config API: %v", err)
return nil, err
}
return cfg, nil
}

该代码使用项目ID来形成其路径;在阅读了lib代码后,我注意到该路径中缺少/projects/;所以我只是把它添加到我的项目ID中,它很有效;-(至少在他们解决这个问题并且我的代码停止工作之前。。

希望这能帮助到别人。

最新更新