精讀《如何在 nodejs 使用環境變數》

黃子毅發表於2018-06-11

1 引言

本期精讀的文章是:如何在 nodejs 使用環境變數

介紹了開發與生產環境如何管理環境變數。

這裡環境變數指的是資料庫密碼等重要資料,而不是指普通變數傳參。

2 概述

環境變數歷史悠久,在執行第一行 JAVA 程式碼之前,你就得將環境變數設定好。

image

可問題是,系統變數並不易用,比如結尾是否要使用分號,JAVA_HOME 與 PATH 在哪些程式中功能相同?而且與作業系統繫結,在作業系統級別設定的變數,給 JAVA 級別的程式用還好,但用來存資料庫密碼就不合適了。

在 Node 中,我們怎樣使用環境變數呢?作者給出瞭如下的建議:

通過命令列傳遞

PORT=65534 node bin/www
複製程式碼

這是最基本、最常用的方式,可是當變數數量過多,不免覺得很崩潰:

PORT=65534 DB_CONN="mongodb://react-cosmos-db:swQOhAsVjfHx3Q9VXh29T9U8xQNVGQ78lEQaL6yMNq3rOSA1WhUXHTOcmDf38Q8rg14NHtQLcUuMA==@react-cosmos-db.documents.azure.com:19373/?ssl=true&replicaSet=globaldb" SECRET_KEY=b6264fca-8adf-457f-a94f-5a4b0d1ca2b9  node bin/www
複製程式碼

作者提到,這種程式碼沒有擴充性。作者認為,對工程師來說,可擴充性甚至比能正確執行更為重要。

使用 .env 檔案

很顯然,命令列寫不下了就寫到檔案裡:

PORT=65534
DB_CONN="mongodb://react-cosmos-db:swQOhAsVjfHx3Q9VXh29T9U8xQNVGQ78lEQaL6yMNq3rOSA1WhUXHTOcmDf38Q8rg14NHtQLcUuMA==@react-cosmos-db.documents.azure.com:10255/?ssl=true&replicaSet=globaldb"
SECRET_KEY="b6264fca-8adf-457f-a94f-5a4b0d1ca2b9"
複製程式碼

通過 dotenv 這個 npm 包可以讀取 .env 檔案的配置到 Nodejs 程式中。

npm install dotenv --save
複製程式碼

安裝後,直接呼叫它解析,就可以從環境變數中拿到 .env 檔案的配置資訊了:

require("dotenv").config();
var MongoClient = require("mongodb").MongoClient;

// Reference .env vars off of the process.env object
MongoClient.connect(
  process.env.DB_CONN,
  function(err, db) {
    if (!err) {
      console.log("We are connected");
    }
  }
);
複製程式碼

這有個問題,不要將配置檔案傳送到 Git 倉庫,可能會洩漏隱私資料。然而 VSCode 幫你解決了這個問題(什麼,你不用 VSCode?)

VSCode 啟動配置

image

VSCode 可以配置 Node 啟動配置,在這裡可以設定環境變數:

image

為了和 .env 檔案打通,我們可以在配置裡設定 envFile 屬性:

{
  "envFile": "${workspaceFolder}/.env"
}
複製程式碼

程式中依然使用 dotenv 讀取環境變數。這麼做將配置保留在 VSCode 中,而不是程式碼中,不用再擔心不小心上傳了配置檔案啦!

使用 Npm Scripts

作者推薦了一個良好的習慣:使用 npm start 執行專案,而不是暴露出 Node 命令。那麼首先在 VSCode launch.json 中配置 Npm 模式:

image

記住,需要給 Node 指令碼新增 --inspect 引數,才能觸發 VSCode debugger 的鉤子:

image

這樣一來,通過 npm start 就可以啟動 Node,並讀取配置在 VSCode 的環境變數。

生產環境的環境變數

上面介紹了本地開發如何使用環境變數,但在生產環境,環境變數必須得換個方式管理。

不知道作者與微軟是什麼關係,這塊推薦了微軟的 Azure 管理環境變數。

主要思路是通過一個不賺差價的中間商提供環境變數管理服務。通過 Azure CLI 啟動你的 Node 專案,就可以從雲服務平臺拿到環境變數資訊。

3 精讀

環境變數管理是非常重要的問題,以前還看到將公司資料庫密碼提交到 Github 的例子,反面教材非常多。

本文介紹了許多本地開發使用環境變數的方式,筆者補充一下生產環境使用環境變數的經驗。

私有部署

如果你在一個高自動化運維水平的公司,這個問題已經被私有 Git + 私有云伺服器天然解決了。

image

是的,部署私有 Git,把資料庫密碼提交到 Git 倉庫才是最完美的方案!

持久化配置服務

通過自建,或者開源的 Azure 持久化配置服務儲存環境變數,在伺服器利用 SDK 獲取它。

一般雲服務商都會打包這項服務,因為只有伺服器和持久化配置服務都由一個供應商提供,供應商才能將持久化配置與伺服器許可權形成關聯,讓第三方伺服器即便拿到 Token 也無法訪問配置。

加密服務

如果安全級別特別高,內部 Git 都不允許提交,又要防止第三方(比如某寬頻運營商)攔截到資訊,就要使用加密服務了。

流程一般是:

  1. 在加密平臺註冊,拿到金鑰。
  2. 在加密平臺設定環境變數,加密平臺會對內容進行加密。
  3. 利用 Node SDK 獲取到加密平臺輸出的密文。
  4. 利用 SDK 和金鑰解密成明文。

4 總結

對待在基礎設施完備公司的同學,可能不需要關心環境變數安全性問題。對於自己搭建部落格,或者使用第三方伺服器的同學,這篇文章告訴我們三個注意點:

  1. 不要將重要環境變數提交到公開的 Git 倉庫。
  2. 本地通過 VSCode 除錯環境變數既方便又安全。
  3. 生產環境通過雲服務商提供的環境變數配置服務拿到環境變數。

5 更多討論

討論地址是:精讀《如何在 nodejs 使用環境變數》 · Issue #89 · dt-fe/weekly

如果你想參與討論,請點選這裡,每週都有新的主題,週末或週一釋出。

相關文章