权限校验中间件必须注册在路由匹配之后、业务handler之前,推荐按路径绑定如app.Get("/admin/*", authMiddleware, handler),失败时须ctx.StatusCode(403)并ctx.StopExecution()中断链路。

权限校验中间件必须放在路由匹配之后、业务 handler 之前
角色权限校验不是登录态检查,而是对已认证用户进一步判断“能否访问该路径”。Iris 不会自动把鉴权逻辑插入执行链,必须显式注册——用 app.Use() 全局生效,或更推荐的 app.Get("/admin/*", authMiddleware, adminHandler) 按路径绑定。若把校验逻辑写进 adminHandler 内部,就失去中间件复用性,且容易漏掉新路由。
常见错误现象:加了中间件但没生效,或部分接口跳过校验。根本原因是注册方式不对:比如只对 /admin 调用了 Use(),但实际路由是 /admin/users,而 Iris 的 Use() 默认不匹配子路径,除非路径参数明确带通配符 *。
- 全局校验:用
app.Use(authMiddleware),但需在中间件内用ctx.Path()+ctx.Method()白名单放行健康检查、登录等免校验路径 - 分组校验:在
admin := app.Party("/admin")后调用admin.Use(authMiddleware),天然覆盖所有/admin/*路由 - 绝对避免:在 handler 里手动调
checkRole()—— 这等于每个接口重写一遍权限逻辑,维护成本爆炸
从 ctx.User 获取用户信息后,必须查角色再比对路径权限
Iris 的 ctx.User.Set(&user) 只是把用户对象挂载到上下文,不包含角色数据。权限校验中间件里不能直接读 user.Role,因为角色可能来自数据库、Redis 或 JWT payload,且一个用户可能有多个角色(如 ["admin", "editor"])。
实操建议:
- 若角色存在 JWT 中,解析时确保 payload 含
roles字段(非role单值),且用jwt.Verify校验后从claims提取 - 若角色查数据库,务必加缓存(如 Redis),避免每次请求都查库;缓存 key 建议用
"user:roles:" + userID - 权限配置建议用映射表:比如
map[string][]string{"GET:/admin/users": {"admin"}, "POST:/api/order": {"user", "admin"}},而非硬编码 if-else - 注意大小写和路径结尾斜杠:/admin 和 /admin/ 是两个不同路径,比对前统一做
strings.TrimSuffix(ctx.Path(), "/")
失败时必须 StatusCode(403) 并 StopExecution(),不能只 return
权限拒绝不是业务错误,而是明确的访问控制响应。只写 return 不会中断中间件链,后续 handler 仍会执行,可能造成数据泄露或状态污染。
正确做法:
- 校验失败立即调
ctx.StatusCode(403),然后ctx.JSON(map[string]string{"error": "forbidden"})或ctx.Text(403, "Forbidden") - 紧跟着必须调
ctx.StopExecution(),这是 Iris 中断当前请求链的唯一可靠方式 - 切勿在
StopExecution()后还调ctx.Next(),会导致 panic - 不要依赖
ctx.StopWithStatus(403):它内部虽含StopExecution(),但默认返回空响应体,前端难调试;建议显式写 JSON 或文本
动态权限更新时,缓存失效和中间件重入问题
用户角色变更(如后台管理员降权)后,若权限数据缓存在 Redis 或本地内存,中间件可能还在用旧角色判断,导致“权限滞留”。
关键点:
- 角色变更操作完成后,必须主动删缓存,如
redis.Del("user:roles:" + userID),不能只等 TTL 过期 - JWT 场景下无法实时失效 token,所以角色字段应设较短
exp(如 30 分钟),并配合 refresh token 机制 - 中间件里禁止用
go func() { ... }()异步查角色 ——ctx不跨 goroutine 安全,异步中调ctx.User.Get()可能 panic 或读到 nil - 测试时容易忽略并发场景:同一用户多个请求同时到达,缓存未命中时可能重复查库,需加单例锁(如
sync.Once或分布式锁)
/api/*)会误拦,写太窄(如 /api/v1/user)又漏掉 /api/v1/user/123;而缓存不及时失效,会让降权用户多保留几十分钟越权能力。这两处不细抠,线上就成安全盲区。


















