【问题标题】:Golang Oauth2 Service account returns empty refresh token stringGolang Oauth2 服务帐户返回空刷新令牌字符串
【发布时间】:2023-01-02 02:59:27
【问题描述】:

尝试使用服务器到服务器身份验证通过服务帐户进行身份验证时,google/Oauth2 包出现问题。 Google 以一个带有空刷新令牌字符串的令牌结构进行响应,令牌将在 1 小时后过期,我无法刷新,因为我没有刷新令牌。 这是我正在使用的代码 sn-p:

data, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", path, serviceAccountFilePath))
if err != nil {
   log.Fatalf("Failed to read GCP service account key file: %s", err)
}
ctx := context.Background()
fmt.Println(scopes)
creds, err := google.CredentialsFromJSON(ctx, data, scopes...)

if err != nil {
   log.Fatalf("Failed to load GCP service account credentials: %s", err)

}
t, _ := creds.TokenSource.Token()
fmt.Println(t.Expiry.Sub(time.Now()).String(), t.RefreshToken, ">>>")

我在使用服务帐户进行身份验证时尝试了不同的方式,例如配置和 JWT,但我仍然得到相同的结果。

【问题讨论】:

  • 将您的令牌源包装在 ReuseTokenSource 中,并且仅在必要时才请求新令牌。
  • 这样 creds.TokenSource = oauth2.ReuseTokenSource(t, creds.TokenSource)?
  • 我认为这是非常多余的,就好像你看一下 func CredentialsFromJSON,它使用这个 func tokenSource 它将在后台调用可重用令牌源

标签: go google-cloud-platform google-oauth service-accounts


【解决方案1】:

服务帐户不需要/使用刷新令牌。

刷新令牌用于标准 Oauth2 授权的离线访问。如果用户离线,则应用程序可以使用刷新令牌获取新的访问令牌并代表用户发出请求。

使用服务帐户,他们已经获得预授权并可以访问他们拥有的数据。一旦访问令牌在一个小时后过期,请求应该返回一个访问令牌,您只需发出新的授权请求以获取新的访问令牌。

对于服务帐户,刷新令牌是不必要的。

google drive api 服务帐户示例。

我不确定您要连接的是什么 api。此示例显示如何使用服务帐户连接到 Google Drive API。 Google api go 客户端库会在需要时自动请求一个新的访问令牌,并将其应用于驱动服务对象。

package main

import (
    "context"
    "fmt"
    "google.golang.org/api/option"
    "log"
    "os"

    drive "google.golang.org/api/drive/v3"
)

// Constants
const (
    ServiceAccount = "C:\Youtube\dev\ServiceAccountCred.json"                  // Please set the json file of Service account.
    filename       = "C:\Development\FreeLance\GoogleSamples\Data\dummy.txt" // Filename
    SCOPE          = drive.DriveScope
)

func main() {

    ctx := context.Background()
    srv, err := drive.NewService(ctx, option.WithCredentialsFile(ServiceAccount), option.WithScopes(SCOPE))
    if err != nil {
        log.Fatalf("Warning: Unable to create drive Client %v", err)
    }

    file, err := os.Open(filename)
    info, _ := file.Stat()
    if err != nil {
        log.Fatalf("Warning: %v", err)
    }

    if err != nil {
        log.Fatalln(err)
    }
    defer file.Close()

    // Create File metadata
    f := &drive.File{Name: info.Name()}

    // Create and upload the file
    res, err := srv.Files.
        Create(f).
        Media(file). //context.Background(), file, fileInf.Size(), baseMimeType).
        ProgressUpdater(func(now, size int64) { fmt.Printf("%d, %d
", now, size) }).
        Do()

    if err != nil {
        log.Fatalln(err)
    }

    fmt.Printf("New file id: %s
", res.Id)
}

【讨论】:

  • 所以你的意思是,如果令牌无效,我应该通过重新验证来创建一个新令牌?你有这样的例子吗?我认为在使用 .Token() 函数时它会处理过期的令牌并返回我回到活跃的那个
  • 你想连接什么api,我会试着给你找个例子。与此同时,这里有一个用于 Google Drive 的 API。对于您只需要更改服务对象的每个 api 来说,它应该是关闭的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 2019-03-20
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
  • 2015-10-01
相关资源
最近更新 更多