跳到主要内容

接口管理

接收前

限制接口访问次数

express-rate-limit

常用配置项解析

windowMs

  • 定义了一个时间范围,用户的请求数会在这个时间范围内被统计
  • 超过时间窗口后,统计会重置
  • 时间窗口的时长,与limit配合使用,代表某个IP在windowMs分钟内的请求次数超过了limit次,该IP的后续请求会被拒绝,直到时间窗口重置为止
  • 默认值 60000 ms (= 1 minute)
const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
const limiter = rateLimit({
windowMs: 15*60*1000,
limit: 100
});

max/limit

  • 当前时间窗口最大的连接数
  • 默认值为 5
  • v7.x版本之后,max改为limit

message

  • 当前时间窗口的拒绝信息
  • 默认值为 'Too many requests, please try again later.'
  • 可以设置为任意类型,建议使用json,也可以是function(req, res), 支持Promise

statusCode

  • 当前时间窗口的拒绝状态码
  • 默认值为 429

handler

  • 当前时间窗口的拒绝处理函数
  • 可以在此处写进错误日志文件file-stream-rotator、或通过 res.status(xxx).send(xxx) 覆盖 messagestatusCode
  • 默认值为 undefined, 相当于handler: (req, res, next, options) => res.status(options.statusCode).send(options.message)

控制返回的 HTTP 响应头

属性头信息名称描述默认启用
legacyHeadersX-RateLimit-Limit 等旧版头使用 X- 前缀的旧版速率限制头
standardHeadersRateLimit-Limit 等标准头使用更符合标准的速率限制头

接收中

1. 日志记录

morgan

morgan

  1. 安装 Morgan

在使用 Morgan 前,需要通过 npm 安装:

npm install morgan
  1. 快速入门

Morgan 提供多种日志格式,可以快速集成到 Express 应用中。

简单示例:

const express = require('express');
const morgan = require('morgan');
const app = express();

// 使用 'dev' 预设格式
app.use(morgan('dev'));

app.get('/', (req, res) => {
res.send('Hello, Morgan!');
});

app.listen(3000, () => {
console.log('Server running on <http://localhost:3000>');
});

运行后,你会看到每次 HTTP 请求的日志,例如:

GET / 200 6.000 ms - 13
  1. 可用的日志格式

Morgan 提供以下内置的日志格式,可以通过第一个参数指定:

  • combined:标准 Apache 风格日志,包含较多信息。
  • common:比 combined 略简化,去掉了 HTTP 版本和响应时间。
  • dev:开发环境使用的简洁彩色输出。
  • short:比 common 更短的信息。
  • tiny:极其精简的日志输出。

示例:切换格式

app.use(morgan('combined')); // 使用 Apache 风格日志
  1. 自定义日志格式

如果内置格式无法满足需求,可以自定义格式。

app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));

// 输出示例:
// GET / 200 123 - 4.567 ms

自定义格式中的占位符:

  • :method:HTTP 方法(如 GET、POST)。
  • :url:请求路径。
  • :status:响应状态码。
  • :res[header]:响应头信息,例如 :res[content-length]
  • :response-time:响应时间(单位 ms)。
  • :remote-addr:请求客户端的 IP 地址。
  • :date:请求日期。
  • 更多占位符请参考 官方文档
  1. 日志输出到文件

可以结合 Node.js 的文件系统模块将日志写入文件。

示例:

const fs = require('fs');
const path = require('path');
const express = require('express');
const morgan = require('morgan');

const app = express();

// 创建日志文件写入流
const accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'),{
flags: 'a', // 追加模式
});

// 使用 'combined' 格式并写入文件
app.use(morgan('combined', { stream: accessLogStream }));

app.get('/', (req, res) => {
res.send('Hello, logs!');
});

app.listen(3000, () => {
console.log('Server running on <http://localhost:3000>');
});
  1. 条件记录日志

可以通过自定义函数筛选需要记录的日志。例如,仅记录状态码为 4xx 或 5xx 的请求。

示例:

app.use(
morgan('dev', {
skip: (req, res) => res.statusCode < 400, // 跳过状态码小于 400 的请求
})
);
  1. 自定义令牌

可以定义自己的令牌以扩展功能。例如,记录用户的 IP 和自定义消息。

示例:

// 添加自定义令牌
morgan.token('user-ip', (req) => req.ip);
morgan.token('custom-message', () => 'Hello Morgan!');

// 使用自定义令牌
app.use(morgan(':method :url :status - :user-ip :custom-message'));
  1. 实现分环境日志

在开发和生产环境中,使用不同的日志格式或配置:

示例:

if (process.env.NODE_ENV === 'production') {
app.use(morgan('combined')); // 生产环境
} else {
app.use(morgan('dev')); // 开发环境
}

2. 安全与性能

静态资源跨域权限控制 - helmet

控制其他域名是否可以访问当前域名下的静态资源(例如图片、脚本、样式等), 设置HTTP头

const helmet = require('helmet');
app.use(helmet.crossOriginResourcePolicy({ policy: 'cross-origin' }));

跨域问题 - CORS

解决跨域问题,哪些域名可以访问当前域名下的 API 接口

const crossOrigin = require('cors');
app.use(crossOrigin(corsOptions));

接收后