我真的很喜欢Django在Heroku上使用dotenv变量的实现,并希望将它带到我们的angular-cli客户端(Angular 2)。
为了在Heroku上运行客户端,我通过运行快速服务器的Node运行应用程序。
Node可以使用process.env.VARNAME访问Heroku的env变量,但我并不了解如何将这些变量传递给我的应用。
如何在我的应用程序中阅读Heroku的变量?
据我所知,在使用angular-cli时,我应该使用environment.ts / environment.prod.ts文件来分隔环境设置。
但是,我不想将这些变量上传到Bitbucket - 这让我回过头来质疑如何从Heroku的变量中设置这些变量(当然process.env.VARNAME没有#t;工作......)
这是推荐的做法还是我错过了什么?
答案 0 :(得分:1)
由于您的服务器是NODE服务器,因此它有可能进行处理,而不是仅提供静态文件。这为您提供了许多选择。
您可以使用由NodeJS服务器处理的模板语言在提供环境变量之前将其嵌入HTML中
您可以拥有一个CONFIG类型端点,其中包含通常存储在环境变量中的配置。您的应用程序在启动时可以访问此端点并获取稍后可以使用的配置数据。
这是我想到的前两个选项 - 但是有很多方法可以解决这个问题。
需要注意的重要一点是,Angular是一个客户端javascript框架,这意味着没有任何安全性 - 任何人使用你的Angular应用程序都可以读取你向Angular发送的任何内容。因此,在您向Angular发送的内容中使用时,请务必不要依赖机密性。
答案 1 :(得分:1)
警告:这不是从heroku访问配置变量的最安全方式。如果你有非常敏感的密钥,你不想容易受到攻击,那么找一个更安全的方法来做这件事。
我使用Heroku-Client API使用node.js从特定的heroku应用程序中提取Config Vars,并使用get请求将它们发送到前端。
//server.js
const express = require('express');
const http = require('http');
const path = require('path');
const Heroku = require('heroku-client')
const heroku = new Heroku({ token: process.env.API_TOKEN })
const app = express();
let API_KEY = '';
app.use(express.static(path.join(__dirname, 'dist')));
heroku.request({
method: 'GET',
path: 'https://api.heroku.com/apps/name-of-app/config-vars',
headers: {
"Accept": "application/vnd.heroku+json; version=3",
"Authorization": "Bearer "+process.env.API_TOKEN
},
parseJSON: true
}).then(response => {
//console.log(response, "heroku api...");
API_KEY = response.API_KEY;
})
app.get('/heroku-env', function(req, res){
res.json(TOKEN);
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'))
});
const port = process.env.PORT || '3001';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
然后使用带HTTP的服务来获取对前端的响应。
//EnvService.js
import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders, HttpRequest } from '@angular/common/http'
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class EnvService{
env:Observable<any> = null;
constructor(private http:HttpClient){}
getEnv() {
console.log("trying to get heroku env...");
this.env = this.http.get('/heroku-env')
return this.env;
}
}
将服务导入app.module,然后在组件中订阅res以访问配置变量。
//my.component.js
import { Component, ViewChild, Inject } from '@angular/core';
import { EnvService } from './env.service';
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent {
defineToken: string = '';
constructor(private envService: EnvService) {}
loadEnv() {
this.envService
.getEnv().subscribe(res => {
this.token = res;
})
}
ngOnInit() {
this.loadEnv();
}
}