Go调用Google API Admin Directory时出现400错误如何解决?
我有一个项目,所有用户均拥有通过G Suite集中管理的Google账号。现在我需要在后端获取所有G Suite用户信息,以便即使用户从未登录过我的工具,也能进行用户搜索。因此我认为后端通过service account连接Google API来获取用户是最佳方案。
为完成认证,我在Google Cloud控制台为一个service account(测试阶段赋予所有者权限)生成了密钥对,保存为JSON文件并传入应用程序。之后我使用返回的服务发起本应返回用户列表的API调用,但不幸的是每次都返回400错误。
我已尝试缩小问题范围,通过调试发现请求头中缺少Bearer token,除此之外未发现其他异常,因此我推测是认证问题,但也可能是其他问题导致。
以下是我的代码:
import ( "context" admin "google.golang.org/api/admin/directory/v1" "google.golang.org/api/option" "log" ) func Test() error { ctx := context.Background() adminService, err := admin.NewService(ctx, option.WithCredentialsFile("./client-secret.json")) if err != nil { return err } res, err := adminService.Users.List().Customer("my_customer").Projection("full").MaxResults(500).Do() if err != nil { return err } log.Printf("Result: %v\n", res) for _, u := range res.Users { println(u.PrimaryEmail) } return nil }
得到的日志信息为googleapi: Error 400: Invalid Input, invalid
我尝试通过Google API获取组织内所有用户,但每次调用都返回400错误,我使用了Google官方Go语言API库,却无法理解错误原因。
问题排查与解决步骤
1. 未配置域范围授权(Domain-Wide Delegation)
服务账号要访问G Suite域内的用户数据,必须在G Suite管理后台开启域范围授权:
- 登录G Suite管理后台,进入「安全」>「API控制」>「域范围委派」
- 点击「添加新」,输入服务账号JSON凭证里的
client_id字段值 - 添加API权限:比如
https://www.googleapis.com/auth/admin.directory.user.readonly(只读用户数据足够),保存设置
2. 代码未指定模拟的管理员账号
调用Admin Directory API时,服务账号必须模拟G Suite域内的超级管理员身份,否则无法生成有效的Bearer Token。修改代码,在创建服务时添加WithSubject选项:
import ( "context" admin "google.golang.org/api/admin/directory/v1" "google.golang.org/api/option" "log" ) func Test() error { ctx := context.Background() // 替换为你的G Suite域超级管理员邮箱 adminEmail := "admin@your-domain.com" adminService, err := admin.NewService(ctx, option.WithCredentialsFile("./client-secret.json"), option.WithSubject(adminEmail), // 关键:指定模拟的管理员账号 ) if err != nil { return err } res, err := adminService.Users.List().Customer("my_customer").Projection("full").MaxResults(500).Do() if err != nil { return err } log.Printf("Result: %v\n", res) for _, u := range res.Users { println(u.PrimaryEmail) } return nil }
3. 确认Admin Directory API已启用
登录Google Cloud控制台,搜索「Admin Directory API」,确保该API处于启用状态。
4. 额外调试手段
如果仍报错,可以添加错误日志选项获取更详细的调试信息:
import "os" // ... adminService, err := admin.NewService(ctx, option.WithCredentialsFile("./client-secret.json"), option.WithSubject(adminEmail), option.WithErrorLogger(log.New(os.Stderr, "admin-api-debug: ", log.LstdFlags)), )
内容的提问来源于stack exchange,提问作者acul21

