- 后端
- 微服务
- 云原生
【免费下载链接】midway
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
导读
@midwayjs/info是 Midway 框架内置的一个轻量级信息展示组件,它像 PHP 的phpInfo()一样,通过一条 HTTP 路由(默认/_info)把当前项目的依赖版本、运行环境、系统资源、环境变量、网络与时间信息等内容以可视化的 HTML 页面呈现出来,同时提供纯 JSON 的输出模式供内部调试与诊断使用。读完本文,你将掌握如何在 Midway 的 Koa / Express / Faas / Egg 应用中接入该组件、自定义标题与路由、按需隐藏敏感配置项(如密钥、Token),以及理解其底层信息采集与脱敏实现原理。
本文以 packages/info/README.md 为骨架,结合该包的源码(src)、默认配置(config.default.ts)与测试用例(test/index.test.ts)展开,所有结论均可在当前仓库中直接验证。
组件是什么:Midway 版的 phpInfo
@midwayjs/info的核心目标是:在应用启动后,通过一个固定的路由展示项目自身的全景运行信息。与phpInfo()的定位类似,它把分散在 Node.js 进程、操作系统、依赖清单和 Midway 容器中的各类元数据集中收敛,方便开发者在联调、排障和交付前快速核对环境。
从源码看,这个组件包体积很小,只依赖一个第三方库picomatch(用于通配符匹配),核心由以下几个文件构成:
- configuration.ts:组件装配入口,负责注册默认配置,并在
onReady阶段把中间件挂载到应用上; - infoService.ts:信息采集与输出的核心服务,聚合了 10 类信息并执行敏感信息脱敏;
- middleware/info.middleware.ts:路由分发中间件,按请求路径命中后返回 HTML;
- utils.ts:HTML 渲染、字节换算、安全脱敏等工具函数;
- interface.ts:配置项类型与信息分类枚举定义。
快速接入:三步开启/_info
接入过程非常简单,只需要在应用的configuration.ts中导入该组件即可。以下示例完整取自 README.md:
import * as info from '@midwayjs/info'; import { join } from 'path'; @Configuration({ imports: [ info, ], importConfigs: [ join(__dirname, './config') ] }) export class ContainerConfiguration { }接入完成后,直接访问curl http://localhost:7001/_info即可看到渲染好的信息页面。默认情况下该页面会以 HTML 表格的形式展示所有信息;如果你在浏览器中查看,效果类似于一个带彩色表头(标题栏为紫色渐变)的信息总览页。
装配阶段的关键逻辑位于 configuration.ts:组件在onReady阶段通过MidwayApplicationManager获取所有koa、faas、express、egg类型的应用实例,并逐一挂载InfoMiddleware。这意味着只要业务应用属于这四类 Web 运行时,接入组件后路由会自动生效,无需手动注册中间件。
配置项详解:标题、路径与敏感信息治理
组件提供了一套默认配置,定义于 config.default.ts,你可以在业务项目的config.default.ts中按需覆盖:
| 配置项 | 默认值 | 类型 | 作用 |
|---|---|---|---|
info.title | 'Midway Info' | string | 信息页面的标题,会渲染在 HTML 页面的顶部横幅中 |
info.infoPath | '/_info' | string | 信息页面的访问路由路径 |
info.hiddenKey | ['keys', '*key', '*token', '*secret*', 'pass*'] | string[] | 需要脱敏的配置/环境变量键名匹配模式(支持通配符) |
info.ignoreKey | [] | string[] | 需要从信息输出中完全剔除的键名 |
对应到 TypeScript 类型定义(见 interface.ts):
export interface InfoConfigOptions { title: string; infoPath: string; hiddenKey: Array<string>; ignoreKey: Array<string>; }自定义路由与标题
例如,你想把信息页放在/status并改名:
// src/config/config.default.ts export default { info: { title: 'My Service Dashboard', infoPath: '/status', }, };需要注意的是,infoPath的生效依赖中间件对ctx.path(Koa/Faas/Egg)或req.path(Express)的精确匹配,见 info.middleware.ts。因此该路径应避免与其他业务路由冲突。
ignoreKey:彻底隐藏某类信息
hiddenKey只做脱敏(隐藏具体值),而ignoreKey会把匹配到的键整体从输出中删除。在 infoService.ts 中可以看到,每一类信息返回后都会经过一次过滤:Object.keys(info).filter(k => !this.ignoreKey.includes(k))。如果你想在对外展示的页面上完全抹掉例如aliyun相关配置,可以这样配置:
export default { info: { ignoreKey: ['aliyun'], }, };hiddenKey的脱敏规则:通配符 + 分级打码
默认的hiddenKey定义在 interface.ts:
export const DefaultHiddenKey = ['keys', '*key', '*token', '*secret*', 'pass*'];在InfoService初始化时,这些模式会被编译为picomatch匹配器(infoService.ts),随后在采集Midway Config与Environment Variable两类信息时对键名做不区分大小写的匹配(isMatch(key.toLowerCase()))。
一旦命中,具体值会通过safeContent进行分级打码(utils.ts),规则非常直观:
| 值长度 | 打码效果 | 示例 |
|---|---|---|
| 0 | 全部替换为空 | '' |
| 1 ~ 2 | 全部替换为* | ab→** |
| 3 ~ 5 | 仅保留首位字符 | abcde→a**** |
| 6 ~ 9 | 保留首尾各 1 位 | abcdef→a****f |
| 10 ~ 14 | 保留首尾各 2 位 | abcdefghijklmn→ab**********mn |
| 15 及以上 | 保留首尾各 3 位 | abcdefghijklmnopq→abc***********opq |
这套规则在 util.test.ts 中有完整的单测覆盖,例如断言safeContent('abcdefghijklmnopq') === 'abc***********opq'。
需要特别留意的是:脱敏是基于键名匹配的。默认模式中的
*key、*token、*secret*、pass*基本覆盖了常见的密钥命名习惯(如accessKeySecret、SecretKey、SecurityToken),但如果你使用了非常规的键名(例如直接叫dbPassword却不含key/token/secret/pass前缀特征),建议将其补充进hiddenKey。
10 类信息全景:InfoService 都采集了什么
InfoService.info()是信息的统一入口(infoService.ts),它依次聚合 10 类信息,每一类都对应一个独立方法:
分类(InfoType) | 采集方法 | 主要内容 |
|---|---|---|
Project | projectInfo() | 项目名称、应用目录(AppDir)、基础目录(BaseDir)、项目根(Root)、当前环境(Env) |
System | systemInfo() | 操作系统平台、Node/V8 版本、进程 ID、架构、主机名、Home 目录、CWD、启动命令行 |
Memory & CPU | resourceOccupationInfo() | 进程 RSS、堆总量、堆使用量、V8 外部内存、系统总内存、CPU 型号/核数/实时占用率 |
Software | softwareInfo() | @midwayjs/core、@midwayjs/decorator、@midwayjs/faas的版本号 |
Environment Variable | envInfo() | 全部进程环境变量(自动脱敏) |
Time | timeInfo() | 当前时间戳、系统运行时长(uptime)、时区与时区名 |
Network | networkInfo() | 各网卡接口的 IP 地址(按 IPv4 优先排序,过滤回环lo) |
Dependencies | dependenciesInfo() | 项目package.json中的全部依赖及其声明版本与本地实际解析版本 |
Midway Service | midwayService() | 当前 IoC 容器注册表中所有服务(含命名空间与作用域标识) |
Midway Config | midwayConfig() | 应用当前的全量配置(自动脱敏) |
其中几处实现细节值得展开:
- 内存换算:所有字节数据通过
bitToMB统一换算为 MB 并以两位小数输出(utils.ts),例如memory.rss、heapTotal、heapUsed、external和totalmem(); - CPU 占用率:基于
os.cpus()每个核心的times统计,按1 - idle/(idle+user+nice+sys+irq)计算并保留两位小数,多个核心之间用/拼接(infoService.ts); - 依赖版本对比:
dependenciesInfo()读取项目package.json的dependencies,再通过safeRequire尝试读取每个依赖自己的package.json拿到实际安装版本,输出形如"4.2.4(^4.2.0)"的“本地版本(声明范围)”格式,若解析失败则标记为Not Found(infoService.ts); - 配置序列化:
safeJson会把配置对象递归序列化为 JSON 字符串,函数类型会输出为function 函数名(N args)形式,便于表格展示(infoService.ts)。
两种输出模式:HTML 页面与 JSON 数据
info()方法的签名支持传入InfoValueType(interface.ts):
export type InfoValueType = 'html' | 'json';- 不传参数(默认):返回
TypeInfo[]数组,即结构化的 JSON 数据,适合程序化消费; - 传入
'html':由renderToHtml渲染成完整的 HTML 字符串(utils.ts),包含标题横幅、分类色块和键值表格,并通过内联<style>保证任何页面打开都有基本样式。
中间件在命中路由时固定输出 HTML 模式(info.middleware.ts)。如果你想在业务代码里直接拿到结构化数据,可以像测试那样注入服务获取:
import { InfoService } from '@midwayjs/info'; const infoService = await app.getApplicationContext().getAsync(InfoService); const json = infoService.info(); // TypeInfo[] 结构 const html = infoService.info('html'); // HTML 字符串这一点在 test/index.test.ts 中也有对应的断言:info()返回的对象键数量大于 5,info('html')输出中包含标题文本Midway Info。
中间件行为:Koa/Faas/Egg 与 Express 的双通道实现
InfoMiddleware根据应用命名空间区分两套处理逻辑(info.middleware.ts):
- Koa / Faas / Egg 风格(默认分支):中间件接收
(ctx, next),当ctx.path === infoPath时直接返回 HTML 字符串(由 Koa 上下文响应),否则调用next()放行; - Express 风格:接收
(req, res, next),当req.path命中时通过res.type('html')+res.send(...)显式返回。
测试用例对两种运行时都做了验证(test/index.test.ts):
- Koa 场景:请求
/_test_route(非信息路由)时正常返回业务内容; - Express 场景:请求
/_info时返回text/html且包含Midway Info标题。
另外,中间件类通过静态getName()返回'info',符合 Midway 中间件命名规范。
安全提示与生产实践建议
由于信息页面会暴露环境变量、依赖清单、全量配置等敏感信息,生产环境使用时有几点建议:
- 严格限制访问范围:
/_info相当于一个应用"体检报告",建议通过网关白名单、内网访问或鉴权中间件保护,避免暴露在公网; - 审查
hiddenKey覆盖度:默认脱敏模式覆盖常见密钥命名,但请结合自身配置命名习惯补齐模式,例如某些厂商的AppSecret、PrivateKey、Password等命名特征; - 善用
ignoreKey:对确实不应出现的整块配置(如内网地址、账号信息),使用ignoreKey从输出中彻底剔除; - 按需调整路由:将
infoPath改为不易被扫描的路径也是一种简单的规避手段。
从源码与测试来看,该组件的脱敏逻辑同时作用于环境变量与配置对象两个采集通道,并且配置对象在递归序列化时也会逐层对键名进行脱敏判断(infoService.ts),安全性设计是成体系的。
相关资源
- 组件 README:packages/info/README.md
- 默认配置:packages/info/src/config.default.ts
- 信息采集核心实现:packages/info/src/infoService.ts
- 路由中间件:packages/info/src/middleware/info.middleware.ts
- 脱敏与渲染工具:packages/info/src/utils.ts
- 集成与脱敏测试:packages/info/test/index.test.ts、packages/info/test/util.test.ts
- 包信息(版本 4.2.4,Node >= 20):packages/info/package.json
- 后端
- 微服务
- 云原生
【免费下载链接】midway
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
相关推荐
Carbon Trigger 浏览器扩展完整实现解析:基于 CO2 Signal API 的电力碳排放强度提醒工具
Carbon Trigger 浏览器扩展完整实现解析:基于 CO2 Signal API 的电力碳排放强度提醒工具 本篇技术指南以 Web Dev For Be
运维性能剖析根因分析可观测性健康检查CANN3步部署BiliBiliToolPro:B站自动签到与账号管理的完整免费方案
3步部署BiliBiliToolPro:B站自动签到与账号管理的完整免费方案 每天醒来第一件事是打开B站?签到、刷两个视频、投两枚币、再溜进直播间发条弹幕——这
后端任务调度工作流自动化使用 @midwayjs/serverless-fc-starter 在阿里云函数计算 FC 上运行 Midway 应用
使用 @midwayjs/serverless fc starter 在阿里云函数计算 FC 上运行 Midway 应用 本指南围绕 packages serv
后端微服务云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考