CORS в Google Apps Script: Как настроить доступ к API?

Что такое CORS (Cross-Origin Resource Sharing)?

CORS (Cross-Origin Resource Sharing) — это механизм безопасности браузера, который ограничивает возможность веб-страниц, запущенных в одном домене, запрашивать ресурсы из другого домена. Это необходимо для предотвращения потенциальных атак, таких как межсайтовый скриптинг (XSS). По умолчанию браузер блокирует запросы, которые нарушают политику одного источника (same-origin policy).

Почему CORS важен для Google Apps Script?

Google Apps Script (GAS) часто используется для создания веб-приложений, API и интеграций с другими сервисами. Когда ваше веб-приложение, размещенное, например, на Netlify или Vercel, пытается получить доступ к API, реализованному в Google Apps Script, браузер может заблокировать запрос из-за CORS. Без правильной настройки CORS ваш API в Google Apps Script будет недоступен для внешних веб-приложений.

Проблемы, которые решает CORS в Google Apps Script

CORS позволяет вашему Google Apps Script API принимать запросы с определенных доменов, что дает вам контроль над тем, кто может получить доступ к вашим данным и функциям. Без CORS ваш API либо будет полностью закрыт для внешних запросов (если не настроено никаких исключений), либо вам придется отключить защиту, что небезопасно.

Настройка CORS в Google Apps Script для доступа к API

Использование doGET(e) и doPOST(e) для обработки запросов

Google Apps Script предоставляет функции doGet(e) и doPost(e) для обработки HTTP-запросов. doGet(e) используется для обработки GET-запросов (обычно для получения данных), а doPost(e) — для обработки POST-запросов (обычно для отправки данных). Параметр e содержит информацию о запросе.

Установка заголовков CORS в ответах Google Apps Script

Чтобы разрешить CORS, необходимо установить определенные HTTP-заголовки в ответе вашего Google Apps Script. Ключевым является заголовок Access-Control-Allow-Origin. Другие важные заголовки: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Max-Age.

Примеры кода для установки заголовков Access-Control-Allow-Origin

Вот пример кода, который показывает, как установить заголовок Access-Control-Allow-Origin в Google Apps Script:

/**
 * Handles GET requests to the script.
 * @param {GoogleAppsScript.Events.DoGet} e Event object containing request information.
 * @return {GoogleAppsScript.HTML.HtmlOutput} Returns an HTML output with CORS headers.
 */
function doGet(e: GoogleAppsScript.Events.DoGet): GoogleAppsScript.HTML.HtmlOutput {
  // Set the origin to allow all domains (* - WARNING: USE WITH CAUTION)
  const origin: string = '*';

  // Create an HTML output
  const output: GoogleAppsScript.HTML.HtmlOutput = HtmlService.createHtmlOutput('CORS Enabled!');

  // Set CORS headers
  output.addMetaTag('Access-Control-Allow-Origin', origin);
  output.addMetaTag('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  output.addMetaTag('Access-Control-Allow-Headers', 'Content-Type');

  // Optional: Allow credentials (cookies, authorization headers)
  output.addMetaTag('Access-Control-Allow-Credentials', 'true');

  return output;
}


/**
 * Handles OPTIONS requests (preflight requests for CORS).
 * @param {GoogleAppsScript.Events.DoGet} e Event object containing request information.
 * @return {GoogleAppsScript.HTML.HtmlOutput} Returns an HTML output with CORS headers.
 */
function doOptions(e: GoogleAppsScript.Events.DoGet): GoogleAppsScript.HTML.HtmlOutput {
  // Allow all origins (WARNING: Use with caution in production)
  const origin: string = '*';

  // Create a blank content output
  const output = HtmlService.createHtmlOutput();

  // Set CORS headers for OPTIONS request
  output.addMetaTag('Access-Control-Allow-Origin', origin);
  output.addMetaTag('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  output.addMetaTag('Access-Control-Allow-Headers', 'Content-Type');
  output.addMetaTag('Access-Control-Max-Age', '3600'); // Cache preflight response for 1 hour

  // Return the output with CORS headers
  return output;
}

Внимание: Использование * в Access-Control-Allow-Origin разрешает запросы со всех доменов. Это может быть небезопасно для production-окружения. Рекомендуется указывать конкретные домены.

Разрешение запросов с определенных доменов

Чтобы разрешить запросы только с определенных доменов, необходимо проверить заголовок Origin в запросе и установить Access-Control-Allow-Origin только если домен запроса находится в списке разрешенных.

/**
 * Handles GET requests with origin validation.
 * @param {GoogleAppsScript.Events.DoGet} e Event object containing request information.
 * @return {GoogleAppsScript.HTML.HtmlOutput} Returns an HTML output with CORS headers.
 */
function doGet(e: GoogleAppsScript.Events.DoGet): GoogleAppsScript.HTML.HtmlOutput {
  const allowedOrigins: string[] = ['https://example.com', 'https://another-example.com']; // Replace with your allowed origins

  // Get the origin from the request headers
  const origin: string | undefined = e.parameters.origin;

  // Check if the origin is allowed
  if (origin && allowedOrigins.includes(origin)) {
    // Create an HTML output
    const output: GoogleAppsScript.HTML.HtmlOutput = HtmlService.createHtmlOutput('CORS Enabled!');

    // Set CORS headers
    output.addMetaTag('Access-Control-Allow-Origin', origin);
    output.addMetaTag('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    output.addMetaTag('Access-Control-Allow-Headers', 'Content-Type');

    return output;
  } else {
    // Origin not allowed, return an error
    return HtmlService.createHtmlOutput('Origin not allowed.');
  }
}
Реклама

Решение проблем с CORS при работе с Google Apps Script

Распространенные ошибки CORS и их причины

  • No 'Access-Control-Allow-Origin' header is present on the requested resource: Эта ошибка возникает, когда сервер (в данном случае, Google Apps Script) не возвращает заголовок Access-Control-Allow-Origin.
  • CORS preflight channel did not succeed: Эта ошибка возникает, когда браузер отправляет OPTIONS-запрос (preflight) перед фактическим запросом, и сервер не отвечает на него с правильными заголовками.
  • Response to preflight request doesn't pass access control check: Эта ошибка возникает, когда preflight-запрос успешно выполнен, но заголовки ответа не соответствуют требованиям браузера (например, заголовок Access-Control-Allow-Methods не содержит используемый метод запроса).

Как проверить заголовки CORS в браузере

Вы можете проверить заголовки CORS в браузере с помощью инструментов разработчика (Developer Tools). Откройте инструменты разработчика (обычно нажатием F12), перейдите на вкладку «Network», найдите запрос к вашему API и проверьте заголовки в секциях «Request Headers» и «Response Headers».

Использование инструментов разработчика для отладки CORS

Инструменты разработчика в браузере предоставляют подробную информацию о CORS-ошибках. В консоли вы увидите сообщения об ошибках, которые указывают на конкретные проблемы с CORS. Также, как было указано выше, можно проверить заголовки запроса и ответа.

Рекомендации по безопасности при настройке CORS

  • Не используйте * в Access-Control-Allow-Origin в production-окружении. Указывайте конкретные домены, которым разрешено отправлять запросы.
  • Ограничьте разрешенные HTTP-методы в Access-Control-Allow-Methods. Разрешайте только те методы, которые необходимы для вашего API.
  • Тщательно проверяйте заголовки запросов. Убедитесь, что ваши Google Apps Script API обрабатывают только ожидаемые заголовки.
  • Используйте HTTPS. Всегда используйте HTTPS для защиты данных, передаваемых между вашим веб-приложением и Google Apps Script API.

Примеры использования CORS в Google Apps Script

Получение данных из стороннего API с использованием CORS

Предположим, у вас есть сторонний API, к которому вы хотите получить доступ из вашего Google Apps Script. Вы можете настроить CORS на стороне этого API, чтобы разрешить запросы с домена вашего скрипта.

/**
 * Fetches data from an external API.
 * @return {object} The JSON response from the API.
 */
function fetchDataFromExternalAPI(): object {
  const url: string = 'https://api.example.com/data';

  const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
    'method': 'get',
    'headers': {
      'Content-Type': 'application/json'
    },
    'muteHttpExceptions': true // Prevent exceptions on non-200 status codes
  };

  try {
    const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url, options);
    const content: string = response.getContentText();
    const json: object = JSON.parse(content);
    return json;
  } catch (e) {
    Logger.log('Error fetching data: ' + e);
    return { error: 'Failed to fetch data' };
  }
}

Создание собственного API с поддержкой CORS в Google Apps Script

Как было показано в предыдущих примерах, вы можете создать свой собственный API в Google Apps Script и настроить CORS для него, чтобы разрешить доступ с определенных доменов.

Интеграция с другими сервисами Google (например, Sheets, Docs) с использованием CORS

Вы можете использовать CORS для интеграции Google Apps Script с другими сервисами Google, такими как Sheets и Docs. Например, вы можете создать веб-приложение, которое отображает данные из Google Sheets, используя API, реализованный в Google Apps Script с настроенным CORS.

Заключение

Краткое описание настройки CORS в Google Apps Script

Настройка CORS в Google Apps Script включает в себя установку HTTP-заголовков Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers в ответах вашего скрипта. Важно внимательно настроить эти заголовки, чтобы обеспечить безопасность вашего API и разрешить доступ только с доверенных доменов.

Дополнительные ресурсы и полезные ссылки


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