Kodokon kodokon.com

配置与密钥

用 dotenv 把配置从代码里抽离出来,把开发环境和生产环境分开,并让你的密钥远离 Git。

8 分钟 · 3 题

在 Kodokon 中打开本课

监听端口、数据库 URL、API 密钥:这些都不该出现在源代码里。这些值在你的机器和生产环境之间会有所不同,而其中一些还是密钥。标准的解决方案是:环境变量,在开发时从一个 .env 文件里加载。用 npm install dotenv 安装 dotenv,然后在项目根目录创建这个文件。

BASH
PORT=3000
DATABASE_URL=postgres://localhost:5432/kodokon
SESSION_SECRET=change-this-value
.env - 每行一个变量

在你入口文件的最开头导入 dotenv/config:文件里的变量会被复制进 process.env。一个良好的职业习惯是:把读取工作集中到一个单独的配置模块里,在启动时校验这些变量,只要缺了一个就立刻失败。一个拒绝启动的服务器,好过一个在第一个请求上就崩溃的服务器。

JAVASCRIPT
import "dotenv/config";

const required = ["PORT", "SESSION_SECRET"];

for (const name of required) {
  if (!process.env[name]) {
    throw new Error("Missing variable: " + name);
  }
}

export const config = {
  port: Number(process.env.PORT),
  secret: process.env.SESSION_SECRET,
  isProd: process.env.NODE_ENV === "production"
};
config.js - 唯一读取 process.env 的模块

在生产环境里,没有 .env 文件:由托管平台提供真实的值,而 NODE_ENVproduction。用 config.isProd 来调整行为:开发时输出详细日志,生产时输出克制的错误信息。另外,提交一个 .env.example 文件,用假值列出所需的变量:它在不暴露密钥的前提下记录了配置。

JAVASCRIPT
import express from "express";
import { config } from "./config.js";

const app = express();

if (!config.isProd) {
  console.log("Development mode");
}

app.listen(config.port, () => {
  console.log("Port: " + config.port);
});
server.js - 其余代码都不用理会 process.env

知识检测

确认你已牢记本课的重点内容。

  1. 你会把数据库密码放在哪里?
    • 放在源代码里的一个常量中
    • 放在一个被 Git 忽略的 .env 文件里
    • 放在项目的 README 里
    • 放在配置文件的一条注释里
  2. .env.example 文件的用途是什么?
    • 用来保存真实的备份值
    • 在不含敏感值的情况下,记录所需的变量
    • 用来配置测试环境
  3. 一个密钥被误提交了。你首先要做什么?
    • 删掉那次提交,然后继续
    • 吊销这个密钥,并生成一个新的
    • 把那个文件加进 .gitignore