您是否将钥匙留在大型停车场的车内? 如果没有,那为什么还要在Github项目中公开API_KEY?
通常使用Cloud服务部署应用程序,但它具有安全性。 云服务需要凭证,通常以API令牌的形式。 鬼nea的黑客搜索这些令牌以用作挖掘加密货币的计算资源或使用它们访问敏感数据。
一种非常普遍的做法是扫描Web和公共工具(例如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项目中获取所有详细信息。
我使用ES6, TypeScript和webpack实现了分配,只是请注意,该解决方案可以在使用webpack的任何其他设置中使用。
使用webpack添加API_KEYS
就我而言,我想要一个非常简单的解决方案,只需为每个部署脚本设置API_KEY。
我使用了webpack的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
变量。
让我们深入了解配置文件
该配置应能够在开发和生产模式下为应用程序提供服务。 当然,如果您使用的是webpack,它还包含HMR(热模式重载)。
这是在开发模式下为应用提供服务的方式:
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。