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

要在Go-Zero项目中为特定接口或整组路由注入自定义中间件,必须让中间件逻辑参与请求响应链,并确保其被正确注册到路由或服务上下文中——否则中间件函数不会被执行,请求将直接跳过你的校验、日志、头信息添加等逻辑。
在API定义中声明中间件名称
打开项目根目录下的 xxx.api 文件,在对应 service 或具体路由上添加 middleware 字段:
// user.api<br>service user-api {<br> @server (<br> timeout: 3s<br> <strong>middleware: authMiddleware</strong><br> )<br> @handler UserListHandler<br> get /api/v1/users (Request) returns (Response)<br>}
这一步是关键前提:【只有在此处声明了 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 {<br> return func(w http.ResponseWriter, r *http.Request) {<br> // ✅ 请求前处理:校验 token、记录 IP、设置 trace-id<br> if token := r.Header.Get("Authorization"); token == "" {<br> http.Error(w, "Unauthorized", http.StatusUnauthorized)<br> return<br> }<br> // ✅ 放行至下一环节(必须调用 next,否则请求中断)<br> next(w, r)<br> // ✅ 响应后处理:写入 X-Processed-Time、清理 context<br> w.Header().Set("X-Processed-Time", time.Now().Format(time.RFC3339))<br> }<br>}
方法二:带依赖注入的结构体写法(推荐用于需访问 config/db/logx 的场景)
在 internal/svc/servicecontext.go 中为中间件注入依赖:
type ServiceContext struct {<br> Config config.Config<br> AuthMw *middleware.AuthMiddleware // ← 显式声明字段<br>}<br><br>func NewServiceContext(c config.Config) *ServiceContext {<br> return &ServiceContext{<br> Config: c,<br> AuthMw: middleware.NewAuthMiddleware(c.JwtConf), // ← 传入配置实例<br> }<br>}
此时 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 头,说明中间件已成功挂载并执行。


















