Google apps script 尝试使用服务帐户从GCS获取对象时获取404
我正在编写一个GoogleApps脚本代码,从GoogleCloudStorage下载一个对象并返回Blob。但是,在下面的调用中运行Google apps script 尝试使用服务帐户从GCS获取对象时获取404,google-apps-script,google-cloud-platform,google-cloud-storage,Google Apps Script,Google Cloud Platform,Google Cloud Storage,我正在编写一个GoogleApps脚本代码,从GoogleCloudStorage下载一个对象并返回Blob。但是,在下面的调用中运行getGcsObjectBlobTest()函数会给我404响应代码,代码主体为“notfound” 我正在使用一个带有秘密JSON密钥的服务帐户进行身份验证。服务帐户具有项目的存储对象查看器角色和bucket的存储对象查看器角色/创建者角色。我没有设置任何表示“用户只需要从云IAM或ACL获得访问bucket或对象的权限”的ACL 有趣的是,如果我在谷歌云控制台
getGcsObjectBlobTest()
函数会给我404响应代码,代码主体为“notfound”
我正在使用一个带有秘密JSON密钥的服务帐户进行身份验证。服务帐户具有项目的存储对象查看器角色和bucket的存储对象查看器角色/创建者角色。我没有设置任何表示“用户只需要从云IAM或ACL获得访问bucket或对象的权限”的ACL
有趣的是,如果我在谷歌云控制台上的object details页面上获取的代码中将URL切换到“Link#2”,我会得到200个带有html主体的响应。所以我想我的IAM至少有一部分在工作
谁能告诉我发生了什么事
function getGcsObjectBlobTest(){
var bucketName = 'vision_api_head_count';
var objectName = 'Sample/Sample_01.jpg';
getGcsObjectBlob(bucketName, objectName);
}
/*
* Get Blob for a GCS object
*
* @param {string} bucketName - bucket name for the object
* @param {string} objectName - name for the object
* @returns Blob
*/
function getGcsObjectBlob(bucketName, objectName){
var googleAppCredentials = getGoogleCredentials();
var scope = 'https://www.googleapis.com/auth/devstorage.read_only';
var token = getOAuth2TokenForGCP('annotatePrivateGcsImage', googleAppCredentials, scope);
// Link #1: This URL is compliant with the official documentation. (https://cloud.google.com/storage/docs/json_api/v1/objects/get)
var url = "https://storage.googleapis.com/storage/v1/b/" + bucketName + "/o/" + objectName + "?alt=media";
// Link #2: This is "Link URL" from Google Cloud Console.
// var url = "https://storage.cloud.google.com/" + bucketName + "/" + objectName + "?alt=media&orgonly=true&supportedpurview=organizationId";
console.log(url);
var options = {
'method' : 'GET',
'headers' : {
'Authorization': 'Bearer ' + token,
}
}
try{
var blob = urlfetch(url, options, true).getBlob();
console.log(blob.getName());
console.log(blob.getContentType());
console.log(blob.getBytes().length + " Bytes");
return blob;
}catch(e){
throw new Error(e);
}
}
/* Get OAuth2 token for specified credentials and scope
*
* @requires {@link https://github.com/gsuitedevs/apps-script-oauth2|OAuth2 for Apps Script}
* @param {string} serviceNamePrefix - prefix for the service name
* @param {string} googleAppCredentials - JSON secret key for an account
* @param {string} scope - {@link https://developers.google.com/identity/protocols/googlescopes|OAuth 2.0 Scopes for Google APIs}
* @returns {string} OAuth 2.0 access token
*/
function getOAuth2TokenForGCP(serviceNamePrefix, googleAppCredentials, scope){
var creds = JSON.parse(googleAppCredentials);
var service = OAuth2.createService(serviceNamePrefix + "_" + creds.client_email)
.setTokenUrl(creds.token_uri)
.setPrivateKey(creds.private_key)
.setIssuer(creds.client_email)
.setSubject(creds.client_email)
.setPropertyStore(PropertiesService.getScriptProperties())
.setCache(CacheService.getScriptCache())
.setLock(LockService.getScriptLock())
.setScope(scope);
if(service.hasAccess()){
return service.getAccessToken();
}else{
console.error(service.getLastError());
throw new Error('Could not get OAuth 2.0 access token!!');
}
}
您使用了错误的端点,这就是您得到404(未找到错误)的原因。您正在使用名为“Authenticated Browser Downloads”的方法,但您正在调用的端点是用于JSON API的 在谷歌云控制台中查找URL URL如下所示,但有几种变体:
https://storage.cloud.google.com/BUCKET_NAME/OBJECT_NAME
我刚刚通过将
encodeURIComponent()
应用于包含“/”的对象名,解决了这个问题。他们应该在文件中提到这一点
var url = "https://storage.googleapis.com/storage/v1/b/" + bucketName + "/o/" + encodeURIComponent(objectName) + "?alt=media";
编辑:输入错误我试图构建一个服务器端应用程序来下载一个对象,所以JSON API就是我想要的。谢谢你努力回答我的问题@t、 toda-不过,我回答了你的问题,为什么你会得到404。