Защита закрытых ключей API с помощью простого прокси-сервера

Две распространенные ошибки, которые допускают разработчики при использовании закрытого API-ключа в своих приложениях, это:

  • Включение ключа API в исходный код
  • включение ключа API в HTTP-запросы на стороне клиента

Раскрытие закрытых API-ключей и токенов авторизации пользователям через HTTP-запросы на стороне клиента и в исходном коде подвергает вас и ваше приложение высокому риску злоупотреблений. Если злоумышленник использует ваш API-ключ для своего приложения, это может стоить вам денег и потенциально лишить вас возможности пользоваться API, превысив лимиты использования.

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

Что такое прокси-сервер?

Прокси-сервер действует как посредник между вашим приложением и API. Он состоит из трех этапов:

  1. Вы отправляете запрос на сервер.
  2. Сервер отправляет запрос в API.
  3. Сервер отвечает на ваш запрос ответом API.

Прокси-сервер, который я собираюсь продемонстрировать здесь, лишь немного более безопасен, чем использование ваших ключей в браузере, поскольку без дополнительных мер предосторожности (например, ограничения домена) другие пользователи могут просто делать запросы через ваш прокси. Я объясню дальнейшие меры предосторожности, которые вы можете принять в конце этой статьи.

Пример базового прокси-сервера

Вот пример прокси-сервера, который я написал, используя Deno. Я использовал Deno, потому что Deno Deploy предлагает бесплатный хостинг, пока он находится в публичной бета-версии (по состоянию на май 2022 года). Если вы посетите Deno Deploy и начнете проект игровой площадки, вы можете попробовать это сами, используя этот код!

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

Этот сервер выполняет запросы к API Twitter. Чтобы аутентифицировать мои запросы, я должен включить заголовок «Authorization» со значением токена на предъявителя. Я буду отправлять запросы на прокси-сервер, а он присоединит заголовок Authorization и отправит запрос на API.

Чтобы делать запросы через прокси, я заменю домен API на домен моего сервера.

Вот пример:

  • Мой сервер расположен по адресу https://my-project.deno.dev.
  • Я хочу отправить запрос к API Twitter по адресу https://api.twitter.com/2/tweets?ids=1261326399320715264.

Чтобы отправить запрос через мой прокси-сервер из моего приложения, я использую этот комбинированный URL: https://my-project.deno.dev/2/tweets?ids=1261326399320715264

import { serve } from "https://deno.land/std@0.137.0/http/server.ts";

const bearer = "Bearer MYBEARERTOKEN";

async function handler(req) {
  const url = new URL(req.url);
  const pathname = url.pathname;

  // Replace server domain with Twitter API domain for the proxy request
  const fetchURL = `https://api.twitter.com${pathname}${url.search}`;

  // Only make proxy request if there is a URL path
  if (pathname.length > 1) {
    const res = await fetch(fetchURL, {
      headers: { Authorization: bearer }
    });

    // If there is a response body, send it as text to the application.
    if (res.body) {
      return new Response(await res.text(), {
        headers: { "Access-Control-Allow-Origin": "*" }
      });
    }
  }
  // If there is no URL path, display "Hello World"
  return new Response("Hello World");
}

serve(handler);
Вход в полноэкранный режим Выход из полноэкранного режима

Дальнейшие меры предосторожности

Как я уже говорил ранее, этот простой прокси-сервер не позволит пользователям увидеть ваши закрытые API ключи в вашем исходном коде и HTTP запросах, но пользователь все равно может делать запросы, используя ваш прокси-сервер.

Для предотвращения этого можно ограничить запросы с других доменов. Просто измените заголовок ответа «Access-Control-Allow-Origin» с «*» на имя хоста, с которого вы хотите принимать запросы. Пример: {"Access-Control-Allow-Origin": "https://www.google.com" }.

Вот и все! Если у вас есть какие-либо мысли по поводу этого метода защиты учетных данных API или другие меры предосторожности, которые вы рекомендуете, пожалуйста, укажите их в комментариях ниже!

Оцените статью
Procodings.ru
Добавить комментарий