Вы оставляете ключи в машине на парковке? Если нет, то почему вы выставляете свои API_KEYs в своих проектах Github?
Развертывание приложений с использованием облачных сервисов является нормой, но сопровождается сложностями безопасности. Для облачных сервисов требуются учетные данные, часто в форме токенов API. Подлые хакеры ищут эти токены для использования в качестве вычислительных ресурсов для майнинга криптовалюты или используют их для доступа к конфиденциальным данным.
Очень распространенной практикой является сканирование интернета и общедоступных инструментов, таких как GitHub, в поиске ключей API, которые по незнанию общедоступны. Это представляет значительные риски как для пользователей, так и для поставщиков облачных услуг.
Основная проблема заключается в том, что исторически разработчики хранили api_keys в коде
Код ниже не так сложно найти,
# src/keys/api_key.js
SOME_SERVICE_API_KEY = '2es8-473t-43ef-a34d' # Don't tell anyone!
Многие разработчики постоянно выставляют свои ключи API в коде, затем они запускают репо и вуаля!
Очевидно, что это наименее безопасный метод, поскольку вы раскрываете важный секрет, который значительно увеличивает риск утечки вашего же секрета.
Я должен был разработать проект как задание, и одним из требований было использование сервисов «The Movie Database API». Способ сделать это - предоставить API_KEY при каждом вызове службы. В моем случае ключ не будет полностью скрыт при запуске приложения.
В любом случае, это дало мне хорошую возможность научиться избегать хранения ключа в самом коде. Вы можете получить все подробности в моем проекте GitHub.
Добавьте API_KEYS с помощью веб-пакета
В моем случае я хотел очень простое решение, в котором я просто установил бы API_KEY для каждого сценария развертывания.
Я использовал веб-пакеты DefinePlugin, что позволило мне создать API_KEY как глобальную константу, которую можно настроить во время компиляции.
new webpack.DefinePlugin({
// Definitions...
});
Это определение в моем файле webpack.config выглядит так:
module.exports = env => {
...
plugins: [
new webpack.DefinePlugin({
'process.env.apiKey': JSON.stringify((env && env.apiKey) || ''),
}),
],
Обратите внимание, что настройка module.exports с функцией, вместо непосредственного присвоения объекта, важно. В противном случае вы не получите доступ к env переменной.
Давайте углубимся в файл конфигурации
Конфигурация должна быть в состоянии обслуживать приложение как в режиме разработки, так и в режиме производства. Конечно, если вы используете веб-пакет, он также включает в себя 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.config, чтобы убедиться, что тот, кто запускает приложение, знает, что API_KEY необходим для запуска сценариев и загрузки приложения.
if (!env || !env.apiKey) {
throw new Error(
'You need to specify your tmdb api-key. You can do so by specifying ' +
'--env.apiKey=<yourkey> in the command line. For example:\n' +
'$ npm run serve-dev -- --env.apiKey=<yourkey>\n' +
' or \n' +
'$ npm run build-webpack -- --env.apiKey=<yourkey> && npm run serve-prod',
);
}
На данный момент у меня все готово в моем конфигурационном файле. Я импортирую этот модуль и возвращаю API_KEY, который я получаю после выполнения команд.
У меня есть следующий код в файле api_key.js, который находится там, где я использую сервис.
export function getApiKey(): string {
if (!process.env.apiKey) {
throw new Error(
'You need to specify your tmdb api-key. You can do so by specifying ' +
'--env.apiKey=<yourkey> in the command line. For example:\n' +
'$ npm run serve-dev -- --env.apiKey=<yourkey>',
);
}
return process.env.apiKey;
}
И сценарии мой package.json выглядит так ...
"serve-dev": "webpack-dev-server --mode=development --config webpack.config.js",
"build:webpack": "webpack --mode=production -p --config webpack.config.js",
"serve-prod": "serve dist",
"test": "jasmine-ts --config=spec/support/jasmine.json",
"test-watch": "nodemon --ext ts --exec 'npm run test'",
Но что происходит с тестовыми сценариями?
Обычно нам не нужен API_KEYS для тестирования. Но в моем случае у меня есть некоторый код в тестах, который косвенно вызывает функцию, которая возвращает API_KEY.
Чтобы избежать использования правильного API_KEY, я добавил в babel.js этот код:
// Global variables needed for api_key.ts.
// The function getApiKey() is not really needed for the tests (we mock the
// access to tmdb), but it is executed as part of the instantiation of the
// Injector class.
process = process || {};
process.env = process.env || {};
process.env.apiKey = 'dummy';
Теперь просто запустите тестовый скрипт npm, не передавая apy_key:
npm run test
Теперь вы должны быть готовы к запуску приложения, не указывая в коде ваши api_keys.
0 комментариев
Добавить комментарий