Получение 404 при попытке получить объект из GCS с использованием служебной учетной записи - PullRequest
0 голосов
/ 08 марта 2020

Я пишу код скрипта Google Apps, чтобы загрузить объект из Google Cloud Storage и вернуть Blob. Однако выполнение функции getGcsObjectBlobTest() в следующем вызове дает мне код ответа 404. Тело "Not Found".

Я использую служебную учетную запись с секретным ключом JSON для аутентификации. Учетная запись службы имеет роль «Просмотр объектов хранилища» для проекта и «Роль / создание создателя объектов хранения» для группы. Я не установил ACL, считая официальной документацией , в которой говорится, что «для доступа к корзине или объекту пользователю требуется только разрешение от Cloud IAM или ACL».

Забавно, если Я переключаю URL-адрес на «Ссылка № 2» в коде, который я получил со страницы сведений об объекте в Google Cloud Console, я получаю ответ 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!!');
  }
}

Ответы [ 2 ]

0 голосов
/ 08 марта 2020

Я только что решил проблему, применив encodeURIComponent() к имени объекта, в котором есть "/". Они должны упомянуть об этом в своем документе

var url = "https://storage.googleapis.com/storage/v1/b/" + bucketName + "/o/" + encodeURIComponent(objectName) + "?alt=media";

edit: typo

0 голосов
/ 08 марта 2020

Вы используете неверную конечную точку, поэтому вы получаете 404 (НЕ НАЙДЕНО ОШИБКА). Вы используете метод «Аутентифицированные загрузки браузера», но вызываемая конечная точка предназначена для JSON API.

Найдите URL-адрес в консоли Google Cloud Console.

URL-адрес выглядит следующим образом, но есть несколько вариантов:

https://storage.cloud.google.com/BUCKET_NAME/OBJECT_NAME

Конечные точки запроса облачного хранилища Google

Загрузки с проверкой подлинности браузера

...