Простой OAuth в скрипте Google Apps

Немного упростить процесс OAuth2 в скрипте Google Apps.

Сценарий Google Apps — это невероятный инструмент, расширяющий функциональные возможности ваших документов, электронных таблиц или презентаций G Suite. Однако на его значение можно не обращать внимания, если вы хотите, чтобы ваш документ взаимодействовал с внешним API, использующим аутентификацию OAuth2.

В этом посте мы рассмотрим шаги, чтобы взять библиотеку OAuth2, предоставленную Google и настроить ее для внешних сервисов, использующих авторизацию Bearer. Это должно охватывать большинство типов конфигурации OAuth2, но если у вас есть что-то уникальное или специфическое, не стесняйтесь комментировать или копаться в примерах по ссылке GitHub.

Здорово! Давайте начнем.

1. Включите скрипт в свой проект

Скрипт Google OAuth2 уже опубликован как скрипт приложений. Это упрощает включение в сценарий. Просто откройте редактор сценариев, а затем:

  1. Нажмите на пункт меню «Ресурсы › Библиотеки…»
  2. В текстовом поле «Найти библиотеку» введите идентификатор сценария 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF и нажмите кнопку «Выбрать».
  3. Выберите последнюю версию.
  4. Нажмите кнопку «Сохранить».

2. Зарегистрируйте свое приложение

Как правило, приложение, для которого требуется OAuth2, также потребует регистрации в этом приложении для получения идентификатора клиента и секрета. На этом экране регистрации обычно вас попросят указать URL-адрес перенаправления. Для скрипта приложений этот URL будет:

https://script.google.com/macros/d/{SCRIPT ID}/usercallback

Это можно легко найти в вашем сценарии, перейдя в «Файл» > «Свойства проекта» и скопировав «Идентификатор сценария».

3. Создание службы OAuth2 в вашем скрипте

Для создания этого скрипта давайте создадим новый файл скрипта для его сохранения. Файл › Создать › Файл скрипта. Я создаю новый файл с меткой OAuth2 для простоты управления кодом.

Когда у нас будет этот скрипт, нам нужно будет настроить службу. Давайте начнем с определения нашего идентификатора клиента и секрета клиента в верхней части нашего файла.

const clientID = '...paste here...';
const clientSecret = '...paste here...';

Теперь нам нужно настроить фактический сервис. Вставьте приведенный ниже код и измените его на основе вашего API.

function getApiService() {
//This service name below will be used when persisting the service authorized token
   //make sure this is unique within your script.
   return OAuth2.createService('The Service Name Here')
//below is where we are setting our token & auth URLs. Usually the URL will end with '/oauth2/token' or 'oauth2/auth'.
   .setAuthorizationBaseUrl('The service Auth URL')
   .setTokenUrl('The service Token URL')
//We are calling our values from the clientID/clientSecret from above.
   .setClientId(clientID)
   .setClientSecret(clientSecret)
//This is a callback function that we are calling. We will use this in another step.
   .setCallbackFunction('authCallback')
   .setPropertyStore(PropertiesService.getUserProperties())
//Depending on your API below are two common settings. Remove if you don't need. Check out the advanced section of the GitHub link for more options.
   .setScope('read-only')
   .setGrantType('authorization_code'); 
}

4. Предоставление пользователю возможности авторизоваться

Теперь мы хотим, чтобы пользователь мог авторизоваться, нажав на ссылку. Сценарий Google Apps требует, чтобы пользователь вручную щелкнул ссылку, поэтому нам нужно динамически передавать ее им на боковой панели. Чтобы сделать мой файл более читабельным, мне нравится помещать его в новый файл сценария под названием «Меню».

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

function onOpen() {
   const ui = SpreadsheetApp.getUi();
   ui.createMenu('My Application Authorization')
   .addItem('Sidebar','showSidebar')
   .addItem('Reset Authentication','reset')
   .addToUi();
}

Затем мы создадим простую функцию, чтобы указать пункт меню «Боковая панель» на наш HTML-файл, который мы вскоре создадим.

function showSidebar() {
   const Authservice = getApiService();
   const html = HtmlService.createHtmlOutputFromFile('sidebar')
   .setTitle('My Application Authorization')
   SpreadsheetApp.getUi()
   .showSidebar(html);
}

Теперь нам нужно создать простую функцию, которая обращается к нашей службе аутентификации и возвращает URL-адрес. Это будет использоваться на боковой панели.

function authorizeSidebar(){
   const Authservice = getApiService;
   const authorizationUrl = Authservice.getAuthorizationUrl();
   return authorizationUrl;
}

Хорошо, что мы только что сделали? Сначала мы создали функцию onOpen. Эта функция создает меню в нашем приложении SpreadsheetApp с двумя опциями: боковая панель и сброс аутентификации. Вы можете использовать любое приложение G Suite, перейдя здесь и нажав Сервисы G Suite. Вы замените SpreadsheetApp на желаемое приложение.

Затем мы создали функцию showSidebar. Эта функция сохраняет наш getApiService() в переменной с именем Authservice. Затем он создает HTML-страницу из нашего HTML-файла и устанавливает заголовок боковой панели. Мы создадим этот HTML-файл на следующем шаге. Если вы назовете свой как-то иначе, вы должны переименовать текст в .createHtmlOutputFromFile().

Наконец, мы создали простую функцию, которая обращается к нашей службе аутентификации, вызывает ее и возвращает URL-адрес. Мы должны быть настроены на создание страницы авторизации!

5. Создание HTML-файла боковой панели

Давайте начнем с создания нового файла и назовем его «боковая панель».
Файл › Создать › HTML-файл

В нашем новом HTML-файле давайте добавим приведенные ниже элементы DIV между тегами body. Они создадут для нас кнопку авторизации и кнопку выхода.

<div>
   <p class="header">First we need to Authorize with our API.</p>
   <button class="btn" id="btn">Authorize</button>
</div>
<div>
   <button id="btn-signout" class="">Sign out of our API</button>
</div>

Далее создадим наш скрипт. Он будет размещен прямо над закрывающим тегом body.

<script>
   document.getElementById("btn").addEventListener("click",authorize);
//this reaches out to the oauth script to add the URL to the authenticate button
   // when the user clicks it they will be directed to the authorization page
   function authorize() {
      google.script.run
      .withSuccessHandler(function(url) {
         window.open(url, '_blank');
      })
      .withFailureHandler(function(err) {
         console.error(err.message);
      })
      .authorizeSidebar();
   }
//this will reset the auth token removing the signin.
   document.getElementById("btn-signout").addEventListener("click",signout);
   function signout() {
      google.script.run.reset();
   }
</script>

6. Обработка authCallback

В наш файл Oauth2.gs нам нужно добавить следующие строки кода:

function authCallback(request) {
   const apiService = getApiService();
   const isAuthorized = apiService.handleCallback(request);
   if (isAuthorized) {
      return HtmlService.createHtmlOutput('Approved. Have fun, ya nerd.');
   } else {
      return HtmlService.createHtmlOutput('Denied. You can close this tab');
  }
}

Этот код сообщает нашему getApiService, что делать после того, как он нажмет «.setCallbackFunction». В этом случае, если обратный вызов возвращается как авторизованный, мы возвращаем одобренный, если это что-то еще, мы возвращаем отклоненный.

7. Создайте боковую панель и протестируйте

Хорошо, теперь мы подошли к тому моменту, когда у нас есть жизнеспособный продукт, и мы должны иметь возможность протестировать боковую панель и ссылку авторизации. Давайте удостоверимся, что мы сохранили всю нашу работу.

Теперь перейдите к файлу menu.gs и выберите функцию «onOpen», затем нажмите «Воспроизвести». Это генерирует в нашем приложении меню.

Теперь мы должны увидеть это в строке меню.

Кроме того, когда мы нажимаем на опцию «Боковая панель», она должна появиться справа.

Ваш сценарий должен вывести вас на экран авторизации в API, который вы настраиваете. После авторизации в этом приложении вы будете перенаправлены на свой скрипт с текстом «Одобрено».

Разве ты не видишь этого? Теперь пришло время устранить неполадки. Возможно, вы неправильно переименовали некоторые функции или вызовы. Откройте консоль Javascript, чтобы увидеть больше информации о любых ваших ошибках. Вы также можете просмотреть журналы Stackdriver в своем скрипте, выбрав View › Stackdriver Logging.

Один из методов устранения неполадок, который я буду использовать, — это добавить «Logger.log («здесь»)» туда, где я считаю ошибкой, чтобы проверить, что скрипт попадает в нее и продолжает работать.

8. Создание функции authorizeURL

Теперь, когда мы настроили базовую авторизацию, мы хотим иметь немного больше контроля над тем, что мы передаем в URL и как. Чтобы сделать наш скрипт OAuth2 немного более модульным, мы создадим функцию, способную обрабатывать наш URL-адрес авторизации.

Добавьте приведенный ниже текст в наш файл OAuth2.gs, и это будет функция, которую мы вызываем каждый раз, когда нам нужен авторизованный URL-адрес.

function authorizeURL(url) {
   const makeService = getApiService();
   const apiFetechedContent = UrlFetchApp.fetch(url,{
      headers: {
         Authorization: 'Bearer ' + makeService.getAccessToken()
         }
    });
const content = apiFetechedContent.getContentText();
   const json = JSON.parse(content);
   return json;
}

Здесь мы создали функцию с именем authorizeURL, в которую мы можем передать параметр URL. Это запускает наш getApiService() и передает наш параметр URL в UrlFetchApp. Предполагая, что мы пытаемся проанализировать содержимое, эта функция также берет содержимое и превращает его в файл JSON, который мы можем легко проанализировать, поскольку он становится объектом.

Теперь, когда мы превратили наш URL-адрес авторизации в функцию, которую мы можем вызывать в любое время, все, что нам нужно сделать, это вызвать это внутри нашей функции и передать переменную URL.

Например:

function testData(){
   const testApiFetechedContent = authorizeURL("https://example.com/api/data");
   const data = testApiFetechedContent.data.test;
}

Приведенный выше код передает наш URL-адрес созданной нами функции authorizeURL, затем с возвращенными данными он переходит к ветке Data, а затем Test.

9. Создайте функцию сброса

Наш последний шаг — создать функцию сброса. Это будет служить нашей функцией выхода из системы, если нам когда-нибудь понадобится сбросить нашу авторизацию с помощью API. Мы уже добавили его в меню на шаге 4, поэтому нам просто нужно создать эту функцию.

Перейдите к файлу OAuth2.gs и добавьте следующий код:

function reset() {
   getApiService().reset();
}

Эта функция проста, она обращается к нашей функции API и сбрасывает значение внутри нее, позволяя вам снова вызвать функцию.

вывод

Мужчина. Это было через многое, и не волнуйтесь, это может стать значительно сложнее. Если у вас есть дополнительные потребности, которые вы не понимаете, я бы посоветовал вам изучить расширенную конфигурацию или примеры GitHub здесь или прокомментировать ниже, и я сделаю все возможное, чтобы помочь!

Первоначально опубликовано на https://coltoneshaw.com 27 июля 2020 г.