使用Golang在Google Admin SDK SDK上获取400 invalid_grant。有什么建议么?

时间:2019-03-25 20:33:04

标签: go google-admin-sdk google-directory-api

我正在尝试制定一个Golang脚本,该脚本使用我的服务帐户来管理我的Google域。尝试创建简单的用户列表时收到错误消息:400 invalid_grant。看来我正确使用了我的服务帐户(?),并且我的服务帐户是超级管理员。我在Java代码中使用凭证;所以我知道这是有效的有什么想法吗?

package main

import (
    "fmt"
    "io/ioutil"
    "log"

    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"
    directory "google.golang.org/api/admin/directory/v1"
)

func main() {
    serviceAccountFile := "/credentials.json"
    serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
    if err != nil {
        log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
    }

    config, err := google.JWTConfigFromJSON(serviceAccountJSON,
        directory.AdminDirectoryUserScope,
        directory.AdminDirectoryUserReadonlyScope,
    )

    // Add the service account.
    config.Email = "serviceaccount@domain.com"

    srv, err := directory.New(config.Client(context.Background()))
    if err != nil {
        log.Fatalf("Could not create directory service client => {%s}", err)
    }

    // The next step fails with:
    //2019/03/25 10:38:43 Unable to retrieve users in domain: Get https://www.googleapis.com/admin/directory/v1/users?alt=json&maxResults=10&orderBy=email&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
    //Response: {
    //  "error": "invalid_grant",
    //  "error_description": "Robot is missing a project number."
    //}
    //exit status 1
    usersReport, err := srv.Users.List().MaxResults(10).OrderBy("email").Do()
    if err != nil {
        log.Fatalf("Unable to retrieve users in domain: %v", err)
    }

    if len(usersReport.Users) == 0 {
        fmt.Print("No users found.\n")
    } else {
        fmt.Print("Users:\n")
        for _, u := range usersReport.Users {
            fmt.Printf("%s (%s)\n", u.PrimaryEmail, u.Name.FullName)
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我已经开始工作了。看来这可能是事物的组合。 DazWilkin,是的,当我切换服务帐户的付款方式时,我收到401未经授权的错误。我做了以下更改。

  1. 在配置中使用主题而不是电子邮件。
  2. 仅使用AdminDirectoryUserScope范围,而不是AdminDirectoryUserReadonlyScope范围(或两者的组合)。
  3. 在请求中包含域。没有它,我会收到400错误的请求。
  4. 我通过以下链接验证了目录API的启用:https://developers.google.com/admin-sdk/directory/v1/quickstart/go。当我单击此链接时,它表示api已经在工作。我在这里使用与其他用其他语言编写的生产脚本中相同的json凭据。意思是,我认为这已经存在。因此,我认为我不需要执行此步骤,但是会在对其他人有用的情况下将其包括在内。

这是我的脚本现在的样子:

package main

import (
    "fmt"
    "io/ioutil"
    "log"

    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"
    directory "google.golang.org/api/admin/directory/v1"
)

func main() {
    serviceAccountFile := "/credentials.json"

    serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
    if err != nil {
        log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
    }

    // I want to use these options, but these cause a 401 unauthorized error
    //  config, err := google.JWTConfigFromJSON(serviceAccountJSON,
    //      directory.AdminDirectoryUserScope,
    //      directory.AdminDirectoryUserReadonlyScope,
    //  )
    config, err := google.JWTConfigFromJSON(serviceAccountJSON,
        directory.AdminDirectoryUserScope,
    )

    // Add the service account.
    //config.Email = "serviceaccount@domain.com" // Don't use Email, use Subject.
    config.Subject = "serviceaccount@domain.com"

    srv, err := directory.New(config.Client(context.Background()))

    if err != nil {
        log.Fatalf("Could not create directory service client => {%s}", err)
    }

    // Get the results.
    usersReport, err := srv.Users.List().Domain("domain.com").MaxResults(100).Do()
    if err != nil {
        log.Fatalf("Unable to retrieve users in domain: %v", err)
    }

    // Report results.
    if len(usersReport.Users) == 0 {
        fmt.Print("No users found.\n")
    } else {
        fmt.Print("Users:\n")
        for _, u := range usersReport.Users {
            fmt.Printf("%s (%s)\n", u.PrimaryEmail, u.Name.FullName)
        }
    }
}

答案 1 :(得分:0)

已修复!

感谢Sal。

这是一个有效的Golang示例:

https://gist.github.com/DazWilkin/afb0413a25272dc7d855ebec5fcadcb6

NB

  • 第24行-config.Subject
  • 第31行-您需要使用此link
  • 包括CustomerId(IDPID

这是一个有效的Python示例:

https://gist.github.com/DazWilkin/dca8c3db8879765632d4c4be8d662074