OAuth2 в Google Apps Script: Как использовать библиотеку для авторизации?

Что такое OAuth2 и зачем он нужен в Google Apps Script?

OAuth2 – это стандарт авторизации, который позволяет приложениям получать доступ к ресурсам пользователей на сторонних сервисах (например, Google Sheets, Google Drive) без необходимости передавать им логин и пароль. В Google Apps Script OAuth2 используется для безопасного доступа к различным Google API и другим сервисам, требующим авторизации.

Представьте, что вы разрабатываете скрипт для автоматической отправки отчетов из Google Sheets в Slack. OAuth2 позволяет вашему скрипту отправлять сообщения в Slack от имени пользователя, не запрашивая его пароль Slack. Это значительно повышает безопасность и удобство использования.

Основные принципы работы OAuth2: Grant Types, Access Token, Refresh Token

OAuth2 работает по следующей схеме:

  1. Приложение запрашивает авторизацию у пользователя. Для этого приложение перенаправляет пользователя на страницу авторизации сервиса (например, Google).
  2. Пользователь предоставляет приложению доступ к своим данным.
  3. Сервис выдает приложению Access Token. Это временный ключ, который приложение использует для доступа к ресурсам пользователя.
  4. Приложение использует Access Token для доступа к API сервиса.
  5. Access Token имеет ограниченный срок действия. Когда срок действия Access Token истекает, приложение использует Refresh Token для получения нового Access Token. Refresh Token выдается вместе с Access Token и позволяет приложению обновлять Access Token без повторного запроса авторизации у пользователя.

Grant Types определяют способ получения Access Token. Наиболее распространенный тип – Authorization Code Grant, который используется в большинстве веб-приложений.

Обзор библиотеки OAuth2 для Google Apps Script: преимущества и возможности

Библиотека OAuth2 для Google Apps Script упрощает процесс реализации OAuth2 авторизации. Она предоставляет удобные функции для:

  • Генерации URL для авторизации.
  • Обмена authorization code на access token.
  • Автоматического обновления access token с использованием refresh token.
  • Проверки срока действия access token.
  • Кэширования токенов для повышения производительности.

Использование библиотеки OAuth2 позволяет разработчикам сосредоточиться на логике своего приложения, а не на сложностях протокола OAuth2.

Подготовка к использованию библиотеки OAuth2

Создание проекта в Google Cloud Platform (GCP) и настройка OAuth 2.0 Client ID

  1. Перейдите в Google Cloud Platform Console.
  2. Создайте новый проект или выберите существующий.
  3. В меню выберите «APIs & Services» -> «Credentials».
  4. Нажмите «Create credentials» и выберите «OAuth client ID».
  5. Выберите тип приложения (например, «Web application»).
  6. Укажите имя вашего приложения.
  7. В поле «Authorized JavaScript origins» укажите URL вашего скрипта Google Apps Script (например, https://script.google.com/).
  8. В поле «Authorized redirect URIs» укажите URL, на который будет перенаправлен пользователь после авторизации (обычно это URL вашего скрипта Google Apps Script с добавлением параметра authcallback). Например: https://script.google.com/macros/s/<YOUR_SCRIPT_ID>/dev или https://script.google.com/macros/s/<YOUR_SCRIPT_ID>/exec.
  9. Нажмите «Create». Сохраните Client ID и Client Secret – они понадобятся вам для настройки библиотеки OAuth2.

Включение необходимых API (например, Google Sheets API, Google Drive API)

  1. В Google Cloud Platform Console перейдите в «APIs & Services» -> «Library».
  2. Найдите и включите API, которые вы планируете использовать (например, Google Sheets API, Google Drive API). Без этого библиотека не сможет получить доступ к API.

Установка библиотеки OAuth2 в Google Apps Script проект

  1. В редакторе Google Apps Script выберите «Libraries» (значок книги).
  2. В поле «Enter a Script ID or URL» введите ID библиотеки OAuth2: 1B7FSorxgnh5z6HiDrF2LqkovV9xKlbMsBJtFWdKGZqnZofDtsBsrsFyz.
  3. Выберите последнюю версию библиотеки.
  4. Укажите alias, например OAuth2.
  5. Нажмите «Add».

Использование библиотеки OAuth2 для авторизации

Создание экземпляра сервиса OAuth2

/**
 * Создает экземпляр сервиса OAuth2.
 *
 * @param {string} serviceName - Имя сервиса.
 * @return {OAuth2.Service} - Экземпляр сервиса OAuth2.
 */
function getOAuthService(serviceName: string): OAuth2.Service {
  const scriptProperties = PropertiesService.getScriptProperties();
  const clientId = scriptProperties.getProperty('CLIENT_ID');
  const clientSecret = scriptProperties.getProperty('CLIENT_SECRET');

  if (!clientId || !clientSecret) {
    throw new Error('Необходимо указать Client ID и Client Secret в свойствах скрипта.');
  }

  return OAuth2.createService(serviceName)
    .setClientId(clientId)
    .setClientSecret(clientSecret)
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
    .setCallbackFunction('authCallback') // Ваша функция обратного вызова
    .setPropertyStore(scriptProperties);
}

Получение URL для авторизации пользователя (Authorization URL)

/**
 * Возвращает URL для авторизации пользователя.
 *
 * @return {string} - URL для авторизации.
 */
function getAuthorizationUrl(): string {
  const service = getOAuthService('googleSheets');
  return service.getAuthorizationUrl();
}
Реклама

Обработка callback URL и получение Access Token

/**
 * Функция обратного вызова, обрабатывающая результат авторизации.
 *
 * @param {Object} request - Объект запроса.
 * @return {HtmlOutput} - HTML-ответ.
 */
function authCallback(request: any): GoogleAppsScript.HTML.HtmlOutput {
  const service = getOAuthService('googleSheets');
  const authorized = service.handleCallback(request);
  if (authorized) {
    return HtmlService.createHtmlOutput('Авторизация прошла успешно! Можете закрыть это окно.');
  } else {
    return HtmlService.createHtmlOutput('Авторизация не удалась. Попробуйте еще раз.');
  }
}

Сохранение и обновление Access Token (использование Refresh Token)

Библиотека OAuth2 автоматически обрабатывает сохранение и обновление Access Token с использованием Refresh Token. Вам не нужно делать это вручную. Она использует PropertiesService для хранения токенов.

Примеры использования OAuth2 библиотеки с различными Google API

Чтение данных из Google Sheets с использованием авторизации

/**
 * Читает данные из Google Sheets.
 *
 * @param {string} spreadsheetId - ID таблицы Google Sheets.
 * @param {string} range - Диапазон ячеек для чтения.
 * @return {any[][]} - Массив данных.
 */
function readDataFromSheets(spreadsheetId: string, range: string): any[][] {
  const service = getOAuthService('googleSheets');
  if (service.hasAccess()) {
    const accessToken = service.getAccessToken();
    const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}`;
    const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    };
    const response = UrlFetchApp.fetch(url, options);
    const data = JSON.parse(response.getContentText());
    return data.values;
  } else {
    const authorizationUrl = service.getAuthorizationUrl();
    Logger.log(`Необходимо авторизоваться: ${authorizationUrl}`);
    throw new Error(`Необходимо авторизоваться. URL: ${authorizationUrl}`);
  }
}

Запись данных в Google Drive с использованием авторизации

/**
 * Creates a new file in Google Drive with the provided content.
 *
 * @param {string} fileName - The name of the file to create.
 * @param {string} fileContent - The content of the file.
 * @param {string} mimeType - The MIME type of the file (e.g., 'text/plain').
 * @returns {string} The ID of the created file.
 */
function createFileInDrive(fileName: string, fileContent: string, mimeType: string): string {
  const service = getOAuthService('googleDrive');

  if (service.hasAccess()) {
    const accessToken = service.getAccessToken();

    const url = 'https://www.googleapis.com/drive/v3/files?fields=id';

    const metadata = {
      name: fileName,
      mimeType: mimeType,
    };

    const multipartBody = `--foo_bar_baz\r\n` +
      `Content-Type: application/json; charset=UTF-8\r\n\r\n` +
      `${JSON.stringify(metadata)}\r\n` +
      `--foo_bar_baz\r\n` +
      `Content-Type: ${mimeType}\r\n\r\n` +
      `${fileContent}\r\n` +
      `--foo_bar_baz--`;

    const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
      method: 'post',
      contentType: 'multipart/related; boundary=foo_bar_baz',
      payload: multipartBody,
      headers: {
        Authorization: 'Bearer ' + accessToken,
      },
      muteHttpExceptions: true, // Prevent throwing errors for non-200 responses
    };

    const response = UrlFetchApp.fetch(url, options);
    const responseCode = response.getResponseCode();
    const responseBody = response.getContentText();

    if (responseCode >= 200 && responseCode < 300) {
      const fileId = JSON.parse(responseBody).id;
      Logger.log(`File created with ID: ${fileId}`);
      return fileId;
    } else {
      Logger.log(`Error creating file: ${responseCode} - ${responseBody}`);
      throw new Error(`Error creating file: ${responseCode} - ${responseBody}`);
    }

  } else {
    const authorizationUrl = service.getAuthorizationUrl();
    Logger.log(`Пожалуйста, авторизуйтесь: ${authorizationUrl}`);
    throw new Error(`Необходимо авторизоваться. URL: ${authorizationUrl}`);
  }
}

Использование OAuth2 для доступа к другим сервисам Google (например, Calendar API, Gmail API)

Аналогичным образом можно использовать OAuth2 для доступа к другим Google API. Просто включите необходимые API в Google Cloud Platform Console и настройте области доступа (scopes) в библиотеке OAuth2 с помощью метода .setScope().

Например, для доступа к Calendar API вам потребуется включить Calendar API в GCP и установить scope https://www.googleapis.com/auth/calendar.

Решение проблем и лучшие практики

Распространенные ошибки при использовании OAuth2 и способы их устранения

  • Неправильный Client ID или Client Secret. Убедитесь, что вы правильно указали Client ID и Client Secret в свойствах скрипта.
  • Неправильный Redirect URI. Убедитесь, что Redirect URI, указанный в Google Cloud Platform Console, соответствует URL вашего скрипта Google Apps Script.
  • Не включены необходимые API. Убедитесь, что вы включили необходимые API в Google Cloud Platform Console.
  • Неправильные области доступа (scopes). Убедитесь, что вы запросили необходимые области доступа в библиотеке OAuth2 с помощью метода .setScope().
  • Проблемы с кэшированием токенов. Очистите кэш браузера или попробуйте использовать другой браузер.

Безопасность OAuth2: хранение credentials и защита от атак

  • Не храните Client Secret в открытом виде. Используйте PropertiesService для хранения Client Secret.
  • Используйте HTTPS. Убедитесь, что ваш скрипт Google Apps Script работает через HTTPS.
  • Проверяйте Access Token. Перед использованием Access Token убедитесь, что он действителен.
  • Защищайте Refresh Token. Refresh Token позволяет злоумышленнику получить Access Token, поэтому его необходимо хранить в безопасном месте.

Отладка OAuth2 в Google Apps Script

  • Используйте Logger.log() для вывода отладочной информации.
  • Используйте Chrome Developer Tools для просмотра сетевых запросов.
  • Проверяйте ошибки в Google Cloud Platform Console.
  • Включите подробное логирование в библиотеке OAuth2 с помощью метода .setVerbose(true). Это может помочь выявить проблемы с авторизацией.

Добавить комментарий