在Go-Zero中为接口注入自定义中间件,需先在xxx.api文件中声明middleware字段,再执行goctl api go生成骨架代码,最后在internal/middleware/中实现逻辑并验证生效。

要在Go-Zero项目中为特定接口或整组路由注入自定义中间件,必须让中间件逻辑参与请求响应链,并确保其被正确注册到路由或服务上下文中——否则中间件函数不会被执行,请求将直接跳过你的校验、日志、头信息添加等逻辑。
在API定义中声明中间件名称
打开项目根目录下的 xxx.api 文件,在对应 service 或具体路由上添加 middleware 字段:
// user.api
service user-api {
@server (
timeout: 3s
middleware: authMiddleware
)
@handler UserListHandler
get /api/v1/users (Request) returns (Response)
}
这一步是关键前提:【只有在此处声明了 middleware 名称,goctl 才会在生成代码时自动创建对应中间件文件并注入调用】。如果只写代码不声明,生成器完全不会感知该中间件存在。
执行 goctl 自动生成中间件骨架
运行命令生成含中间件结构的完整服务代码:
goctl api go --api user.api --dir .
执行后,internal/middleware 目录下会自动出现 authmiddleware.go(名称与 api 中声明的一致,小写+驼峰转下划线),其中已包含空的 Handle 方法签名和基本包声明。
注意:若目录不存在或生成失败,请确认 goctl 已安装且版本 ≥ v1.7.0;旧版可能不支持 middleware 字段解析。
填充中间件核心逻辑
编辑 internal/middleware/authmiddleware.go,按需编写处理逻辑。典型结构如下:
方法一:基础函数式写法(适合简单逻辑)
func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// ✅ 请求前处理:校验 token、记录 IP、设置 trace-id
if token := r.Header.Get("Authorization"); token == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// ✅ 放行至下一环节(必须调用 next,否则请求中断)
next(w, r)
// ✅ 响应后处理:写入 X-Processed-Time、清理 context
w.Header().Set("X-Processed-Time", time.Now().Format(time.RFC3339))
}
}
方法二:带依赖注入的结构体写法(推荐用于需访问 config/db/logx 的场景)
在 internal/svc/servicecontext.go 中为中间件注入依赖:
type ServiceContext struct {
Config config.Config
AuthMw *middleware.AuthMiddleware // ← 显式声明字段
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
AuthMw: middleware.NewAuthMiddleware(c.JwtConf), // ← 传入配置实例
}
}
此时 AuthMiddleware 结构体可持有 JwtConf、logx.Logger 等,实现更复杂的鉴权或审计逻辑。
验证中间件是否生效
第一步:启动服务
go run user.go -f etc/user-api.yaml
第二步:发起测试请求
curl -H "Authorization: Bearer xxx" http://localhost:8888/api/v1/users
第三步:观察终端日志输出或响应 Header
若看到你写的 logx.Info 日志,或响应中包含 X-Processed-Time 头,说明中间件已成功挂载并执行。











