如何通过PowerShell借助JSON对象连接Google API?
使用PowerShell通过服务账号连接Google API
嘿,既然你已经拿到了Google服务账号的JSON密钥,那咱们直接上手用PowerShell对接API就行!我给你整理了两种靠谱的实现方式,按需选择就好:
第一步:先把密钥存好
建议把你的JSON密钥保存成本地文件,比如命名为service-account-key.json——比起直接嵌在脚本里,文件方式不仅安全,后续修改也方便。当然你要是偏爱硬编码,直接在脚本里用ConvertFrom-Json解析JSON字符串也没问题。
第二步:获取访问令牌
Google服务账号得通过JWT签名来换取访问令牌,这里给你两种方法:
方法1:用Google官方PowerShell模块(推荐,省事儿)
先装GoogleCloud模块,这个是官方维护的,稳定性拉满:
Install-Module -Name GoogleCloud -Scope CurrentUser -Force
导入模块后,用密钥文件激活服务账号:
Import-Module GoogleCloud gcloud auth activate-service-account --key-file=".\service-account-key.json"
之后想拿令牌直接跑这条命令就行:
$token = gcloud auth print-access-token
拿到令牌后,就能用它调用各种Google API了。
方法2:手动构造JWT(不用装模块,适合自定义场景)
要是不想装模块,咱们手动实现JWT签名也不难,下面是完整的示例脚本:
# 加载本地密钥文件(或者直接把JSON字符串放这里解析) $serviceAccount = Get-Content -Path ".\service-account-key.json" | ConvertFrom-Json # 配置JWT的基础参数 $currentTime = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds() $tokenExpiry = $currentTime + 3600 # 令牌默认有效期1小时,足够用了 $jwtHeader = @{ alg = "RS256" typ = "JWT" } | ConvertTo-Json -Compress # 这里的scope要换成你实际需要的API权限范围,比如Drive API就用"https://www.googleapis.com/auth/drive" $jwtPayload = @{ iss = $serviceAccount.client_email scope = "https://www.googleapis.com/auth/cloud-platform" aud = $serviceAccount.token_uri exp = $tokenExpiry iat = $currentTime } | ConvertTo-Json -Compress # 把Header和Payload转成Base64Url格式(Google要求的格式) function ConvertTo-Base64Url { param([string]$InputString) $bytes = [System.Text.Encoding]::UTF8.GetBytes($InputString) $base64 = [System.Convert]::ToBase64String($bytes) # 替换掉Base64里的特殊字符,符合JWT要求 return $base64.Replace('+', '-').Replace('/', '_').TrimEnd('=') } $encodedHeader = ConvertTo-Base64Url $jwtHeader $encodedPayload = ConvertTo-Base64Url $jwtPayload $signatureInput = "$encodedHeader.$encodedPayload" # 用服务账号的私钥签名 $privateKey = [System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromPem($serviceAccount.private_key) $rsaProvider = $privateKey.GetRSAPrivateKey() $signatureBytes = $rsaProvider.SignData( [System.Text.Encoding]::UTF8.GetBytes($signatureInput), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1 ) $encodedSignature = ConvertTo-Base64Url ([System.Convert]::ToBase64String($signatureBytes)) # 拼接成完整的JWT $jwtToken = "$encodedHeader.$encodedPayload.$encodedSignature" # 向Google令牌端点请求访问令牌 $tokenResponse = Invoke-RestMethod -Uri $serviceAccount.token_uri -Method Post -Body @{ grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer" assertion = $jwtToken } # 提取出可用的访问令牌 $accessToken = $tokenResponse.access_token Write-Host "成功获取访问令牌:$accessToken"
注意:一定要把scope换成你要调用的API对应的权限范围,不然会出现权限不足的错误。
第三步:调用Google API示例
拿到令牌后,咱们用Cloud Storage API举个例子,列出你的项目下的存储桶:
$apiEndpoint = "https://storage.googleapis.com/storage/v1/b?project=$($serviceAccount.project_id)" $requestHeaders = @{ Authorization = "Bearer $accessToken" } $apiResponse = Invoke-RestMethod -Uri $apiEndpoint -Headers $requestHeaders # 输出存储桶名称和创建时间 $apiResponse.items | Select-Object name, timeCreated
踩坑提醒
- 别忘了在Google Cloud控制台给你的服务账号分配对应API的角色,比如要访问Storage就得加「Storage Viewer」或者更高权限的角色,不然调用API会报403错误。
- 令牌有效期只有1小时,要是脚本需要长时间运行,记得加个逻辑自动刷新令牌。
- 要是用方法2遇到签名错误,检查下私钥的格式有没有问题——你的JSON里的私钥已经带了
-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----,直接用就行,不用额外处理。
内容的提问来源于stack exchange,提问作者Heather
相关产品推荐
相关产品推荐

