2017-03-19 44 views
1

我真的很喜歡Django在Heroku上使用dotenv變量的實現,並希望將它帶入我們的angular-cli客戶端(Angular 2)。使用Heroku環境變量和角度cli,通過節點服務器部署

爲了在Heroku上運行客戶端,我通過運行express服務器的節點運行應用程序。

  1. 節點可以訪問使用process.env.VARNAME Heroku的ENV變量,但我不明白如何將這些變量傳遞給我的應用程序。
    如何在應用程序中讀取Heroku的變量?

  2. 據我所知,當使用angular-cli時,我應該使用environment.ts/environment.prod.ts文件來分離環境設置。

    不過,我不希望這些上傳到瓦爾到位桶 - 這把我帶回了質疑如何設置從Heroku的瓦爾這些變量(當然process.env.VARNAME不工作...)

這是推薦的做法還是我錯過了什麼?

+0

什麼是要注入到客戶端的東西呢?無論是在環境中還是在源代碼中,它們都不會安全,因爲它們最終無法控制用戶的設備。 – jonrsharpe

+0

評論heroku:https://devcenter.heroku.com/articles/node-best-practices#be-environmentally-aware :: environment:process.env.NODE_ENV || '生產', –

+0

剛剛發現[這個答案](http://stackoverflow.com/questions/41348751/heroku-pipeline-with-angular-2-environments),它實際上是我需要的,但作爲不可能的答案。 任何人都知道如何去做建議呢? 「更好的選擇可能是讓您的Angular2應用在初始化時查詢您的服務器」 –

回答

0

由於您的服務器是NODE服務器,因此它有可能執行處理,而不是僅提供靜態文件。這給你一些選擇。

  1. 您可以使用您的NodeJS服務器處理的模板語言嵌入環境變量到HTML爲它服務

  2. 您可以使用包含通常存儲在環境變量中配置的配置類型的端點之前。啓動後,您的應用程序可以訪問此端點並獲取稍後可以使用的配置數據。

這些是想到的前兩個選項 - 但有很多方法可以處理這個問題。

重要的是要注意的是,Angular是一個客戶端JavaScript框架,這意味着沒有任何安全性 - 任何您發送到Angular的任何人都可以使用您的Angular應用程序閱讀。因此,重要的是您不要依賴保密性來確定您向Angular發送的內容。

0

警告:這不是從heroku訪問config vars最安全的方法。如果你有非常敏感的密鑰,你不想被攻擊,那麼找一個更安全的方法來做到這一點。

我使用Heroku-Client API從特定的heroku應用程序中使用node.js提取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.write(API_KEY); 
    res.end(); 
}); 


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 { Http, Response, RequestOptions, Headers, Request, RequestMethod } 
from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class EnvService{ 

    env:Observable<any> = null; 

    constructor(private http:Http){} 

    getEnv() { 
    console.log("trying to get heroku env..."); 
    this.env = this.http.get('/heroku-env').map(response => response) 
    return this.env; 
    } 
} 

將服務導入到app.module中,然後訂閱組件中的res以訪問config vars。

//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.defineToken = res._body; 
    }) 
    } 

    ngOnInit() { 
    this.loadEnv(); 
    } 
} 

引用:https://github.com/heroku/node-heroku-client