Как авторизовать скрипт приложения в веб-интерфейсе? - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть простой скрипт приложения, который ищет на диске папку с именем «что-то» и перечисляет имена файлов внутри, если папка не существует, он создает ее.

function doGet() {
 var folders = DriveApp.getFoldersByName('something');
 if (folders.hasNext()) {
  var files = folders.next().getFiles();
    var fileNames  = [];
    while (files.hasNext()) {
      var file = files.next();
      fileNames.push(file.getName())
    };
    return ContentService.createTextOutput(JSON.stringify({
        'status': 'success',
        'output': fileNames
    }))

  } else {
    DriveApp.createFolder('something');
    return ContentService.createTextOutput(JSON.stringify({
        'status': 'success',
        'output': 'folder created'
    }))
  }
}

Я развертываю сценарий как веб-приложение, запускаю приложение как сам, проверяю его, используя вызов выборки из приложения реагирования в браузере, и все работает как положено.

Затем я переиздаю как веб-приложение, выполнив как пользователь, обращающийся к веб-приложению. На этот раз ничего не работает. Я получаю следующую ошибку в браузере

Доступ к выборке на «https://script.google.com/macros/s/AKfycbx4eQ60DziUy4hSjnJidW9WVwBsT_qruQHa_BrK508T4oD9ILY/exec' из источника 'http://localhost:3000' заблокирован политикой CORS: Ответ на предполетный запрос не проходит проверку контроля доступа: Нет Заголовок «Access-Control-Allow-Origin» присутствует в запрошенном ресурс. Если непрозрачный ответ удовлетворяет вашим потребностям, установите запрос режим 'no-cors' для извлечения ресурса с отключенным CORS.

Я ожидал ошибку, так как нет аутентификации. Я настроил google OAuth2 в приложении реагирования, добавил сценарии и области действия дисков, зарегистрировал приложение в консоли разработчика Google и настроил все так, чтобы я получил accessToken, который я могу отправить в заголовке с вызовом fetch для скрипта google .

Но я все еще получаю ту же ошибку, что и выше.

Как я должен авторизовать приложение-скрипт, чтобы каждый мог его запустить?

Я пытаюсь создать веб-приложение с кнопкой входа в систему google, когда пользователь, входящий в него, вызывает развернутый мной appscript и ищет на его диске имена папок «что-то», чтобы я мог отобразить имена файлов в моем веб-приложении.

Это не проблема cors, если я запускаю веб-приложение от себя, проблем с cors не возникает и ноль изменений в коде. Мой вопрос касается того, как я авторизую скрипт приложения? Я упоминаю только ошибку cors, потому что я показывал то, что я пробовал до сих пор.

1 Ответ

1 голос
/ 03 апреля 2019

Вы получите ошибку CORS, если какая-либо функция в вашем вызове вызовет исключение, так как у вас нет обработчика try...catch. Когда развернутое веб-приложение не может вернуть действительный ответ (т. Е. HtmlOutput или TextOutput) , страница ошибок Google не содержит заголовков CORS.

Чтобы предотвратить эти «маскирующие» ошибки CORS, оберните точки входа вашего веб-приложения с помощью try...catch, чтобы можно было сообщить о фактической ошибке.

Даже без переноса точек входа вашего веб-приложения с помощью try...catch весьма вероятно, что вы сможете получить доступ к основной ошибке, просмотрев журналы Stackdriver / отчеты об ошибках Stackdriver вашего проекта.

Это простой пример, демонстрирующий проверку некоторого объекта события, чтобы убедиться, что запрос находится где-то, о чем вы заботитесь, и правильно ли он сформирован, а затем вызывает функцию, которая может вызвать исключение для недопустимых / неавторизованных операций. В любом случае он возвращает непрозрачный пользовательский ответ («Извините!») И при ошибках генерирует журнал Stackdriver. Он не может перехватить исключение, которое возникает при нарушении квоты времени выполнения, поскольку ваш скрипт просто уничтожен.

function doGet(e) {
  if (!e || !validate_(e)) {
    return fail_();
  }
  try {
    return walkDriveContent(...);
  }
  catch (err) {
    console.error({message: "Drive walk failed: " + err.message, stack: err.stack, error: err});
    return fail_();
  }
}

function fail_() {
  return ContentService.createTextOutput("Sorry!");
}

function validate_(eventObj) {
 /** your code here that ensures this is a valid event object you can work with */
 // return true;
 //     or
 // return false;
}

function walkDriveContent(folderName) {
  /**
   * Your code that may throw exceptions here, but otherwise
   * returns TextOutput or HtmlOutput
   */
}
...