我正在尝试编写一个 golang 脚本,该脚本使用我的服务帐户来管理我的 google 域。当我尝试做一个简单的用户列表时出现错误:400 invalid_grant。看来我正在正确使用我的服务帐户(?),而且我的服务帐户是 super 管理员。我在 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)
}
}
}
最佳答案
我得到了这个工作。看起来它可能是多种因素的结合。 DazWilkin,是的,当我切换传入服务帐户的方式时,我收到了 401 未经授权的错误。我做了以下更改。
- 在配置中使用主题而不是电子邮件。
- 只使用了 AdminDirectoryUserScope 范围,而不是 AdminDirectoryUserReadonlyScope 范围(或两者的组合)。
- 在请求中包含域。如果没有它,我会收到 400 Bad Request。
- 我通过以下链接验证了目录 API 已打开:https://developers.google.com/admin-sdk/directory/v1/quickstart/go .当我点击这个链接时,它说 apis 已经在工作了。我在这里使用的 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)
}
}
}
关于go - 使用 golang 在 google admin sdk api 上获取 400 invalid_grant。有什么建议么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55345991/