无需gcloud/命令行:通过GCP服务账号JSON密钥生成访问令牌
使用服务账号JSON认证调用Google Artifact Registry Docker端点
Golang 实现方案
直接借助Google官方OAuth2库自动处理签名与Token生成,无需手动计算签名逻辑:
- 安装依赖:
go get golang.org/x/oauth2/google
- 完整代码示例:
package main import ( "context" "fmt" "io" "net/http" "os" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) func main() { // 加载服务账号JSON密钥文件 keyPath := "/path/to/your/service-account-key.json" keyData, err := os.ReadFile(keyPath) if err != nil { fmt.Printf("读取服务账号密钥失败: %v\n", err) return } // 配置JWT认证,指定Artifact Registry所需权限范围 config, err := google.JWTConfigFromJSON(keyData, "https://www.googleapis.com/auth/cloud-platform") if err != nil { fmt.Printf("创建JWT配置失败: %v\n", err) return } // 获取自动处理Token刷新的HTTP客户端 ctx := context.Background() client := config.Client(ctx) // 调用Artifact Registry Docker端点 registryURL := "https://<region>-docker.pkg.dev/v2/_catalog" resp, err := client.Get(registryURL) if err != nil { fmt.Printf("请求失败: %v\n", err) return } defer resp.Body.Close() // 读取并打印响应 body, _ := io.ReadAll(resp.Body) fmt.Printf("响应状态: %s\n", resp.Status) fmt.Printf("响应内容: %s\n", string(body)) }
关键说明
- 替换
/path/to/your/service-account-key.json为你的服务账号密钥实际路径 - 替换
<region>为目标GCP区域(如us-central1) - 权限范围可改用更精细的
https://www.googleapis.com/auth/artifactregistry.readonly,遵循最小权限原则
Postman 配置方案
无需命令行交互,通过预请求脚本自动生成Bearer Token:
创建环境变量,添加以下项:
service_account_json:粘贴你的服务账号JSON完整内容region:目标GCP区域token_url:固定值https://oauth2.googleapis.com/token
在请求的预请求脚本中添加以下代码:
// 解析服务账号JSON const sa = JSON.parse(pm.environment.get("service_account_json")); const now = Math.floor(Date.now() / 1000); const expiry = now + 3600; // Token有效期1小时 // 构造JWT头部与载荷 const header = { alg: "RS256", typ: "JWT" }; const payload = { iss: sa.client_email, scope: "https://www.googleapis.com/auth/cloud-platform", aud: pm.environment.get("token_url"), exp: expiry, iat: now }; // Base64URL编码工具函数 function base64urlEncode(str) { return btoa(JSON.stringify(str)) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, ""); } const encodedHeader = base64urlEncode(header); const encodedPayload = base64urlEncode(payload); const signInput = `${encodedHeader}.${encodedPayload}`; // 使用服务账号私钥签名 const privateKey = sa.private_key; const signature = CryptoJS.SHA256(signInput, privateKey).toString(CryptoJS.enc.Base64url); const jwt = `${encodedHeader}.${encodedPayload}.${signature}`; // 请求Google获取Bearer Token pm.sendRequest({ url: pm.environment.get("token_url"), method: "POST", header: { "Content-Type": "application/x-www-form-urlencoded" }, body: { mode: "urlencoded", urlencoded: [ { key: "grant_type", value: "urn:ietf:params:oauth:grant-type:jwt-bearer" }, { key: "assertion", value: jwt } ] } }, function (err, res) { if (err) { console.error(err); } else { const token = res.json().access_token; pm.environment.set("bearer_token", token); pm.request.headers.add({ key: "Authorization", value: `Bearer ${token}` }); } });
- 设置请求URL为
https://{{region}}-docker.pkg.dev/v2/_catalog,发送请求即可自动完成认证。
关键说明
- Postman内置CryptoJS库,无需额外引入
- 权限范围同样可替换为
https://www.googleapis.com/auth/artifactregistry.readonly
内容的提问来源于stack exchange,提问作者Ashutosh Kumar Pandey
相关产品推荐
相关产品推荐

