怎么在 Node.js Express 中实现自定义 API Key 鉴权中间件?

文章导读
在 Node.js Express 中实现自定义 API Key 鉴权中间件,核心是编写一个检查 req.headers 的函数,验证通过后调用 next(),失败则返回 401 状态码。该方案适合服务端间调用鉴权,需注意密钥不应硬编码在代码库中。
📋 目录
  1. A 快速处理思路
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

在 Node.js Express 中实现自定义 API Key 鉴权中间件,核心是编写一个检查 req.headers 的函数,验证通过后调用 next(),失败则返回 401 状态码。该方案适合服务端间调用鉴权,需注意密钥不应硬编码在代码库中。

先说结论:自定义中间件通过拦截请求头实现访问控制,是 Express 处理身份验证的标准模式。

  • 适合:内部服务通信、公开 API 的访问限制。
  • 优先做:将密钥存储在环境变量而非代码文件中。
  • 再验证:使用 curl 或 Postman 发送带/不带 Key 的请求测试拦截效果。

快速处理思路

不需要复杂库,直接编写函数检查请求头。定义中间件函数,读取 x-api-key 或自定义 header,比对预期值,匹配则放行,不匹配则中断响应。通过 app.use() 全局注册或绑定到特定路由。

为什么会这样

Express 中间件按注册顺序执行,可以在业务逻辑前统一拦截。中间件本质是具有特定签名的函数,包含请求对象 (req)、响应对象 (res) 和 next 回调函数。请求从外向内穿透中间件层,响应则反向返回,这种设计使复杂处理流程可视化。

分步处理

1. 创建中间件函数。定义一个接收 req, res, next 三个参数的函数。

2. 获取请求头数据。使用 req.headers['x-api-key'] 读取客户端传递的密钥。

3. 执行比对逻辑。将获取的密钥与服务端存储的正确密钥进行字符串比对。

4. 控制流程流转。验证成功调用 next() 传递控制权,验证失败调用 res.status(401).json() 返回错误并结束请求。

5. 注册中间件。使用 app.use() 全局应用,或在特定路由前使用。

怎么在 Node.js Express 中实现自定义 API Key 鉴权中间件?
const apiAuth = (req, res, next) => {\n  const apiKey = req.headers['x-api-key'];\n  if (!apiKey || apiKey !== process.env.EXPECTED_API_KEY) {\n    return res.status(401).json({ error: 'API key required' });\n  }\n  next();\n};\napp.use('/api', apiAuth);

怎么验证是否生效

使用 curl 命令发送不带 Key 的请求,应返回 401 状态码。发送带正确 Key 的请求,应返回 200 状态码或进入后续业务逻辑。检查服务器日志确认中间件是否被触发。

curl -i http://localhost:3000/api/test\ncurl -i -H "x-api-key: your_secret_key" http://localhost:3000/api/test

常见坑

1. 忘记调用 next()。验证通过后必须执行 next(),否则请求会挂起超时。

2. 密钥硬编码。不要将密钥直接写在代码里,应通过环境变量管理。

3. 大小写敏感。HTTP 请求头在小写处理上可能因环境而异,建议统一转为小写比对。

4. 错误处理中间件位置。确保错误处理中间件放在所有中间件之后,否则可能拦截不到鉴权错误。

常见问题

全局中间件和路由级中间件有什么区别?

全局中间件通过 app.use() 无路径参数注册,拦截所有请求;路由级中间件绑定特定路径,只拦截匹配该路径的请求。

API Key 应该存放在哪里?

建议存放在服务器环境变量或配置中心,不要提交到版本控制系统,生产环境需定期轮换。

参考来源

  • Node.js 中间件开发:实现自定义中间件并应用于 Express 框架 - 简书
  • 如何在 Node.js 中使用 API Key 进行权限验证?
  • Node.js 中间件开发:实现自定义中间件的方法
  • Node.js 自定义中间件
  • Nodejs -- Express 自定义中间件并进行封装