在 public GitHub 存储库中使用 AWS 凭证(在 node.js 项目中,使用 Grunt.js 构建)
Using AWS credentials in a public GitHub repo (in a node.js project, built with Grunt.js)
我们有一个 MEAN(nodes.js 后端 + angular 前端),我们在其中使用 Amazon S3 sdk 将文件上传到存储服务。我们有我们的 AWS 凭证,我们需要在代码中使用它们。
我们想在 public 存储库中发布我们的项目,但我们不想共享我们的凭据(顺便说一下,Amazon 会监控 GitHub 并通知披露其凭据的开发人员).我们应该如何调整我们的开发工作流程以获得安全(不公开)和方便的东西?
解决方案包括调整 Gruntfile.js 文件,该文件定义了构建过程中需要完成的工作。根据您用作起点的那个,情况会有所不同(并且可能需要考虑各种用例)。
在我们的例子中,我们使用 angular 全栈 yeoman 生成器 (https://github.com/DaftMonk/generator-angular-fullstack) 生成项目框架。生成器生成的 Gruntfile.js 相当复杂,因此我们不得不编辑几个部分。以下是要点:
1。将参数传递给 Grunt
我们首先需要的是能够调用构建过程并传递参数。参数不应最终出现在存储库中,因此开发人员应在代码库 之外创建脚本 以启动构建过程(或每次手动输入参数...)。 Grunt 提供了使用 grunt.option()
函数访问命令行参数的能力。因此,对 Gruntfile.js 文件的第一个修改是在开头添加以下两行:
module.exports = function (grunt) {
var amznUserId = grunt.option('AMZN_USER_ID');
var amznUserPassword = grunt.option('AMZN_USER_PASSWORD');
...
}
如果您这样做,然后通过键入调用 grunt:
grunt build --AMZN_USER_ID=myUserId --AMZN_USER_PASSWORD=aSecret
grunt serve --AMZN_USER_ID=myUserId --AMZN_USER_PASSWORD=aSecret
然后您将在脚本变量中获得可用的凭据值。
2。在源文件中添加占位符
AMZN 凭据用于 Angular.JS 组件,通常在控制器中。您需要做的是用变量占位符替换硬编码值,如下所示:
angular.module('demoApp')
.controller('MainCtrl', function ($scope, $http, socket) {
$scope.amzn_user_id = '@@AMZN_USER_ID';
$scope.amzn_user_password = '@@AMZN_USER_PASSWORD';
3。将命令行参数注入占位符
解决方案的最后(也是最棘手的)部分是将传递给 grunt 的 2 个值注入占位符。有不同的 Grunt 插件可用于此目的。我们成功地使用了 grunt-replace
插件。这是我们必须做的:
3.1 安装插件
npm install grunt-replace --save
3.2 配置插件(指定注入应该如何发生,最后详细介绍)
grunt.initConfig({
replace: {
dist: {
options: {
patterns: [
{
match: 'AMZN_USER_ID',
replacement: amznUserId
},
{
match: 'AMZN_USER_PASSWORD',
replacement: amznUserPassword
}
]
},
files: [
{
expand: true,
flatten: false,
src: ['.tmp/concat/app/app.js'],
dest: '.'
},
{
expand: false,
flatten: false,
src: ['client/app/main/main.controller.js'],
dest: '.tmp/app/main/main.controller.js'
}
]
}
},
3.3。在 grunt build
和 grunt serve
工作流程中调用插件
请注意顺序很重要,replace
行必须正好位于该位置。
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'env:all', 'env:prod', 'express:prod', 'wait', 'open', 'express-keepalive']);
}
if (target === 'debug') {
return grunt.task.run([
'clean:server',
'env:all',
'injector:stylus',
'concurrent:server',
'injector',
'wiredep',
'autoprefixer',
'concurrent:debug'
]);
}
grunt.task.run([
'clean:server',
'env:all',
'injector:stylus',
'concurrent:server',
'injector',
'wiredep',
'replace',
'autoprefixer',
'express:dev',
'wait',
'open',
'watch'
]);
});
和
grunt.registerTask('build', [
'clean:dist',
'injector:stylus',
'concurrent:dist',
'injector',
'wiredep',
'useminPrepare',
'autoprefixer',
'ngtemplates',
'concat',
'replace',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin'
]);
幕后发生了什么
关键是要意识到 angular 全栈生成器定义了一个构建工作流,其中使用了一个名为 .tmp
的特殊目录。这个目录的内容并不总是相同的(grunt build
和 grunt serve
使用它的方式略有不同)。这就是我们必须定义两个替换规则的原因。
我们有一个 MEAN(nodes.js 后端 + angular 前端),我们在其中使用 Amazon S3 sdk 将文件上传到存储服务。我们有我们的 AWS 凭证,我们需要在代码中使用它们。
我们想在 public 存储库中发布我们的项目,但我们不想共享我们的凭据(顺便说一下,Amazon 会监控 GitHub 并通知披露其凭据的开发人员).我们应该如何调整我们的开发工作流程以获得安全(不公开)和方便的东西?
解决方案包括调整 Gruntfile.js 文件,该文件定义了构建过程中需要完成的工作。根据您用作起点的那个,情况会有所不同(并且可能需要考虑各种用例)。
在我们的例子中,我们使用 angular 全栈 yeoman 生成器 (https://github.com/DaftMonk/generator-angular-fullstack) 生成项目框架。生成器生成的 Gruntfile.js 相当复杂,因此我们不得不编辑几个部分。以下是要点:
1。将参数传递给 Grunt
我们首先需要的是能够调用构建过程并传递参数。参数不应最终出现在存储库中,因此开发人员应在代码库 之外创建脚本 以启动构建过程(或每次手动输入参数...)。 Grunt 提供了使用 grunt.option()
函数访问命令行参数的能力。因此,对 Gruntfile.js 文件的第一个修改是在开头添加以下两行:
module.exports = function (grunt) {
var amznUserId = grunt.option('AMZN_USER_ID');
var amznUserPassword = grunt.option('AMZN_USER_PASSWORD');
...
}
如果您这样做,然后通过键入调用 grunt:
grunt build --AMZN_USER_ID=myUserId --AMZN_USER_PASSWORD=aSecret
grunt serve --AMZN_USER_ID=myUserId --AMZN_USER_PASSWORD=aSecret
然后您将在脚本变量中获得可用的凭据值。
2。在源文件中添加占位符
AMZN 凭据用于 Angular.JS 组件,通常在控制器中。您需要做的是用变量占位符替换硬编码值,如下所示:
angular.module('demoApp')
.controller('MainCtrl', function ($scope, $http, socket) {
$scope.amzn_user_id = '@@AMZN_USER_ID';
$scope.amzn_user_password = '@@AMZN_USER_PASSWORD';
3。将命令行参数注入占位符
解决方案的最后(也是最棘手的)部分是将传递给 grunt 的 2 个值注入占位符。有不同的 Grunt 插件可用于此目的。我们成功地使用了 grunt-replace
插件。这是我们必须做的:
3.1 安装插件
npm install grunt-replace --save
3.2 配置插件(指定注入应该如何发生,最后详细介绍)
grunt.initConfig({
replace: {
dist: {
options: {
patterns: [
{
match: 'AMZN_USER_ID',
replacement: amznUserId
},
{
match: 'AMZN_USER_PASSWORD',
replacement: amznUserPassword
}
]
},
files: [
{
expand: true,
flatten: false,
src: ['.tmp/concat/app/app.js'],
dest: '.'
},
{
expand: false,
flatten: false,
src: ['client/app/main/main.controller.js'],
dest: '.tmp/app/main/main.controller.js'
}
]
}
},
3.3。在 grunt build
和 grunt serve
工作流程中调用插件
请注意顺序很重要,replace
行必须正好位于该位置。
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'env:all', 'env:prod', 'express:prod', 'wait', 'open', 'express-keepalive']);
}
if (target === 'debug') {
return grunt.task.run([
'clean:server',
'env:all',
'injector:stylus',
'concurrent:server',
'injector',
'wiredep',
'autoprefixer',
'concurrent:debug'
]);
}
grunt.task.run([
'clean:server',
'env:all',
'injector:stylus',
'concurrent:server',
'injector',
'wiredep',
'replace',
'autoprefixer',
'express:dev',
'wait',
'open',
'watch'
]);
});
和
grunt.registerTask('build', [
'clean:dist',
'injector:stylus',
'concurrent:dist',
'injector',
'wiredep',
'useminPrepare',
'autoprefixer',
'ngtemplates',
'concat',
'replace',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin'
]);
幕后发生了什么
关键是要意识到 angular 全栈生成器定义了一个构建工作流,其中使用了一个名为 .tmp
的特殊目录。这个目录的内容并不总是相同的(grunt build
和 grunt serve
使用它的方式略有不同)。这就是我们必须定义两个替换规则的原因。