
在 API 开发和测试的过程中,多应用、多环境的鉴权管理往往是一个令人头疼的问题。频繁地复制粘贴 Token 不仅低效,还容易出错;而将敏感凭证(如 Client Secret 或 Password)直接写在脚本或环境变量中,又会带来严重的安全隐患(例如被意外提交到 Git 仓库)。
本文将介绍一个基于 Bruno(一款开源的轻量级 API 客户端)的实战方案。通过该方案,我们将针对 Identity Server 的 OAuth2 获取 Token 接口,实现跨越两个应用(APP1 和 APP2)以及 3 个环境(dev → qas → prd)的高效测试。更重要的是,它展示了一种在绝对不将敏感信息提交到 Git 的前提下,优雅管理多环境凭证的最佳实践。
项目结构解析
首先,我们来看一下整个 Bruno Collection 的目录结构:
.
├── .env # 本地敏感凭证(已加入 .gitignore,绝不提交)
├── .gitignore
├── opencollection.yml # Bruno Collection 配置文件
├── environments/
│ ├── dev.yml # 各个环境的非敏感配置
│ ├── qas.yml
│ └── prd.yml
├── app1/
│ ├── folder.yml # 目录级前置脚本:从 .env 自动加载敏感凭证
│ └── idp.yml # POST /oauth2/token 请求
└── app2/
├── folder.yml # 目录级前置脚本:从 .env 自动加载敏感凭证
├── idp.yml # POST /oauth2/token 请求
├── health_check.yml
└── health_check (Apigee).yml
核心设计决策
这套方案之所以能够兼顾安全与便捷,主要得益于以下三个核心设计:
1. 环境配置文件仅存放非敏感信息(可提交至 Git)
在 environments/ 目录下的配置文件中,我们只保留非敏感信息,并在其中声明敏感变量的占位符。
# environments/qas.yml
variables:
- name: env
value: qas
- name: idp_base_url
value: idp.{{env}}.xxx.com
- name: grant_type
value: password
- name: client_secret
value: ""
secret: true # 在此声明,以便 Bruno 在 UI 中对其进行掩码遮挡
2. .env 文件存放真实的敏感凭证(被 Git 忽略)
真实的凭证信息被存放在项目根目录的 .env 文件中。由于该文件已被 .gitignore 忽略,因此绝不会被提交到代码仓库。
APP1_QAS_CLIENT_ID=xxxx
APP1_QAS_CLIENT_SECRET=xxxx
APP1_QAS_PASSWORD=xxxx
💡 提示:这里的关键在于命名规范。我们将每个变量命名为
APP_ENV_VAR的形式(例如APP1_QAS_CLIENT_ID),从而实现多应用、多环境变量的清晰隔离。
3. 利用目录级前置脚本(Pre-request Script)动态绑定
我们在每个应用目录(如 app1/)下创建 folder.yml 前置脚本。该脚本会在该目录下的所有请求执行前运行,自动桥接 .env 中的凭证。
// app/folder.yml — 在该目录下每个请求执行前运行
const envName = bru.getEnvName().toUpperCase(); // 例如 "QAS"
const app = "APP1";
// 根据当前环境和应用,动态从系统环境变量(.env)中读取并设置 Bruno 变量
bru.setEnvVar("client_id", bru.getProcessEnv(`${app}_${envName}_CLIENT_ID`));
bru.setEnvVar(
"client_secret",
bru.getProcessEnv(`${app}_${envName}_CLIENT_SECRET`)
);
bru.setEnvVar("password", bru.getProcessEnv(`${app}_${envName}_PASSWORD`));
通过这种方式,当我们通过 Bruno 右上角的下拉菜单切换环境时,脚本会自动提取对应的凭证,完全免去了手动复制粘贴的繁琐操作。
快速开始
如果你想在团队中推行这套方案,只需遵循以下步骤:
- 克隆项目:将代码仓库克隆到本地,并在 Bruno 中打开该 Collection。
- 配置本地凭证:向团队成员索要或自行创建
.env文件,填入你个人的敏感信息:APP1_QAS_CLIENT_ID=your_value APP1_QAS_CLIENT_SECRET=your_value APP1_QAS_PASSWORD=your_value # ... 根据你需要测试的应用和环境重复上述配置 - 选择环境:在 Bruno 右上角的下拉菜单中选择目标环境(例如
qas)。 - 一键运行:直接运行任意请求,脚本会在后台自动为你加载对应的敏感信息。
总结:为什么这种模式行之有效?
我们将这套方案带来的收益总结如下表所示:
| 核心诉求 | 解决方案 |
|---|---|
| 敏感信息不泄露 | .env 文件被 Git 忽略;环境配置(environments/*.yml)中仅保留 secret: true 的空占位符。 |
| UI 界面隐私保护 | 变量声明为 secret: true 后,即使通过 bru.setEnvVar() 赋值,Bruno 也会在界面上自动进行掩码处理。 |
| 多环境无缝切换 | 只需在 UI 中一键切换环境,前置脚本会自动解析环境名称并匹配对应的 .env 键值。 |
| 多应用互相隔离 | 各目录前置脚本中的 app 常量(如 APP1、APP2)有效限定了变量读取的作用域。 |
| 生产环境差异化配置 | 对于域名特殊的生产环境,直接在 prd.yml 中硬编码生产域名,无需再依赖 \{\{env\}\} 变量插值。 |
这套基于 Bruno 的实践,不仅保持了 API 调试的敏捷性,更在团队协作中守住了安全底线。如果你也在寻找一款轻量、纯文本驱动且对开发者友好的 API 客户端,不妨尝试一下 Bruno 与这套工作流。