RRuna

HTTP 中间件总览

把日志、恢复、限流、认证、安全 Header 等横切能力接入路由

中间件适合处理所有 HTTP 请求都可能用到的横切逻辑,比如 panic 恢复、请求 ID、真实 IP、访问日志、CORS、CSRF、请求体大小限制、超时、静态文件、登录态、权限、限流和审计。

Runa 的中间件类型是 route.Middleware,本质是 func(route.Handler) route.Handler。它只属于 HTTP route 传输块,不进入微内核,也不是 Provider。普通应用开发者只需要理解三件事:安装需要的包、把中间件挂到合适位置、把依赖能力先通过 runa.Install 装好。

安装

只使用路由机制时安装 route:

go get github.com/duxweb/runa/route

使用官方内置 HTTP 中间件时安装 middleware 模块:

go get github.com/duxweb/runa/middleware

语言协商中间件是独立模块:

go get github.com/duxweb/runa/middleware/lang

使用组合安全预设时安装 security 模块:

go get github.com/duxweb/runa/security

业务中间件按能力单独安装,比如 session、auth、rate、audit:

go get github.com/duxweb/runa/session github.com/duxweb/runa/auth github.com/duxweb/runa/rate github.com/duxweb/runa/audit

最小示例

package main

import (
    "context"

    "github.com/duxweb/runa"
    "github.com/duxweb/runa/route"
    "github.com/duxweb/runa/security"
)

func main() {
    app := runa.New()
    app.Install(route.Provider(route.Addr(":8080")))

    route.Default().Use(security.New(security.Production()))
    route.Default().Get("/", func(ctx *route.Context) error {
        return ctx.Text("ok")
    })

    if err := app.Run(context.Background()); err != nil {
        panic(err)
    }
}

挂载位置

全局挂载,适合 recover、request id、real ip、logger、security 这类全站逻辑:

route.Default().Use(mw)

分组挂载,适合只保护某一组接口:

api := route.Default().Group("/api")
api.Use(mw)

单路由挂载,适合只给少数接口加权限或限流:

route.Default().Get("/profile", profile).Use(mw)

执行顺序

中间件按注册顺序进入,按相反顺序退出:

route.Default().Use(A(), B(), C())
A before -> B before -> C before -> handler -> C after -> B after -> A after

通常推荐顺序:

  1. recover 最外层,兜住后续中间件和 handler 的 panic
  2. requestid 早注册,让日志、审计、错误响应都能拿到请求 ID
  3. realip 早注册,让日志、限流、审计拿到真实 IP
  4. logger 记录最终状态码和耗时
  5. bodylimittimeout 保护资源
  6. helmetcors 设置响应 Header
  7. sessionauthrateaudit 按业务需要挂到分组或路由

如果不想自己组合基础链路,可以直接用 Security 生产预设

跳过请求

大多数官方中间件都有 Next func(*route.Context) bool 配置。返回 true 表示跳过当前中间件。

route.Default().Use(logger.New(logger.Config{
    Next: func(ctx *route.Context) bool {
        return ctx.Request().URL.Path == "/health"
    },
}))

适合跳过 /health/metrics、静态文件、内部回调等请求。

页面索引

页面 适合解决的问题
Recover 捕获 panic,避免进程因为单个请求崩溃
Request ID 给每个请求生成追踪 ID
Real IP 从可信代理读取真实客户端 IP
Logger 记录 HTTP 访问日志、慢请求和错误请求
CORS 允许浏览器跨域访问 API
CSRF 保护浏览器表单和 Cookie 登录态接口
Body Limit 限制请求体大小,避免大包拖垮服务
Timeout 给普通 HTTP 请求设置最大执行时间
Helmet 写入常见安全 Header
Healthcheck 快速提供 /health 健康检查
Static 挂载本地静态文件目录
Security 一次接入生产常用安全链路
Session 在请求中加载和保存会话
Auth 登录态、可选登录和权限检查
Rate Limit 按 IP、用户或自定义键限流
Audit 记录业务操作审计日志

新手怎么选择中间件

可以按这个顺序理解:

  1. 先加基础保护:recover、requestid、realip、logger、bodylimit、timeout、helmet
  2. 如果有浏览器跨域,再加 CORS
  3. 如果有浏览器表单或 Cookie 登录态,再加 CSRF
  4. 如果有登录态,再加 session 和 auth
  5. 如果接口容易被刷,再加 rate
  6. 如果后台操作需要追踪,再加 audit

如果不想逐个配置,先用 安全预设 起步,再按项目需要微调。

如果你只做一个内部极简 HTTP 服务,也可以只挂 recover.New()requestid.New()。Runa 不强制安装任何中间件,所有中间件都按需 import、按需挂载。

编辑此页