Запустите приложение без указания ключей API в коде

Вы оставляете ключи в машине на большой парковке? Нет? Тогда почему вы выставляете свой api_key в своих проектах GitHub?

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

Подлые хакеры ищут эти токены, чтобы использовать их в качестве вычислительных ресурсов для добычи криптовалюты или для доступа к конфиденциальным данным.

Распространенной практикой является сканирование Интернета и общедоступных инструментов, таких как GitHub, в поисках ключей API, которые неосознанно являются общедоступными. Это представляет значительные риски как для пользователей, так и для поставщиков облачных услуг.

Проблема с ключами API

Основная проблема в том, что исторически разработчики хранят api_key в коде.

Приведенный ниже код найти не так уж и сложно.

# src/keys/api_key.js
SOME_SERVICE_API_KEY = '2es8-473t-43ef-a34d' # Don't tell anyone!

Многие разработчики постоянно выставляют свои ключи API в коде, затем вставляют в свое репо, и вуаля!

Очевидно, что это наименее безопасный метод, поскольку вы раскрываете важный секрет, который значительно увеличивает риск утечки вашего секрета.

Мне нужно было разработать проект в качестве задания, и одним из требований было использование службы API базы данных фильмов.

Для этого нужно указывать api_key при каждом вызове службы. В моем случае ключ не будет полностью скрыт во время работы приложения.

В любом случае, для меня это была хорошая возможность узнать, как не хранить ключ в самом коде. Я воспользовался возможностью, чтобы поделиться здесь своим опытом. Подробности читайте в моем GitHub project.

Я реализовал задание с помощью ES6, TypeScript и webpack. Просто обратите внимание, что это решение будет работать с любым другим параметром, использующим webpack.

Добавьте ключи API с помощью Webpack

В моем случае мне нужно очень простое решение, в котором я бы просто установил api_key для каждого сценария развертывания.

Я использовал DefinePlugin из webpack, что позволило мне создать api_key как глобальную константу, которую можно настроить во время компиляции.

new webpack.DefinePlugin({
  // Definitions...
});

Это определение в моем файле webpack.config выглядит так:

Обратите внимание, что установка module.exports с функцией важна вместо непосредственного назначения объекта. В противном случае вы не получите доступа к переменной env.

Глубоко в файле конфигурации

Конфигурация должна поддерживать приложение в режиме разработки и производства.

Конечно, если вы используете webpack, он также включает HMR (Hot Mode Reload).

Вот как обслужить приложение в режиме разработки:

TMDB_API_KEY=<yourTmdbApiKey>
npm run serve-dev  -- --env.apiKey=${TMDB_API_KEY}

И обслуживайте его в производственном режиме:

TMDB_API_KEY=<yourTmdbApiKey>
npm run build:webpack -- --env.apiKey=${TMDB_API_KEY} && \
 npm run serve-prod

Обратите внимание, что в обоих случаях мне нужно явно указать webpack, что я передаю ключ.

Обратите внимание на то, что -- как аргумент сам по себе стандартизирован для всех команд Unix. Это означает, что дальнейшие аргументы следует рассматривать как позиционные аргументы, а не варианты.

В этом контексте это означает, что параметры после -- должны быть отправлены команде serve-dev или build:webpack, в зависимости от выполняемого вами сценария.

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

На данный момент у меня все готово в моем файле конфигурации. Я импортирую этот модуль и возвращаю api_key, который я получаю после выполнения команд.

У меня есть следующий код в файле api_key.js, который находится там, где я использую службу.

А сценарий в моем package.json выглядит так:

Сценарии тестирования

Но что происходит с тестовыми сценариями?

Обычно нам не нужны ключи API для тестирования, мы должны имитировать вызовы. Я знаю, но в моем случае у меня есть код в тестах, который косвенно вызывает функцию, возвращающую api_key.

Если вы находитесь в подобной ситуации, вы можете сделать то же самое, что и я. Чтобы избежать использования правильного api_key, я добавил этот код в babel.js:

Теперь просто запустите тестовый скрипт npm, не передавая apy_key:

npm run test

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

Спасибо за прочтение! Если у вас есть предложения или идеи, дайте мне знать.