Fiber不处理越权校验,因其仅为轻量级Web框架,仅负责路由分发与请求解析,无内置业务语义判断;越权防护必须在业务handler内实时比对请求主体与资源归属,不可依赖路由或全局中间件。

为什么 Fiber 本身不处理越权校验
Fiber 是一个轻量级 Web 框架,它的职责是路由分发、中间件编排和响应控制,ctx.Params、ctx.Query、ctx.Body 只负责解析原始请求数据,不内置任何业务语义判断。所谓“用户 A 请求 /user/123 却拿到用户 B 的数据”,本质是业务逻辑漏洞(IDOR),不是框架能自动拦截的。Fiber 不会、也不该替你决定“谁可以查谁的数据”。
在 Fiber 中做参数归属校验的实操位置
越权防护必须落在业务 handler 内部或紧邻 handler 的中间件里,不能依赖路由层或全局过滤器——因为只有在这里,你才同时拥有:ctx.UserContext()(当前登录用户 ID)、被请求的资源 ID(比如 ctx.Params("id"))、以及访问目标资源所需的 DAO 或 Service 实例。
- 不要在中间件里直接查 DB 判断归属:中间件应只做身份认证(如验证 Token)和基础鉴权(如角色白名单),避免把业务逻辑下沉到通用层
- 推荐在 handler 开头立即校验:先取
ctx.Params("id"),再用当前用户 ID 查询数据库确认该记录是否属于他;不匹配就直接ctx.Status(403).SendString("forbidden")并 return - 如果多个接口都要校验同一种关系(如“订单必须属当前用户”),可封装成函数:
checkOrderOwnership(ctx, orderID, userID),而不是注解或反射式切面——Fiber 没有 Spring 那套 AOP 生态,硬套反而增加维护成本
常见错误:把路由参数当可信输入
很多人误以为 app.Get("/user/:id", handler) 中的 :id 经过路由匹配就“安全了”,其实它只是字符串提取,没有任何类型或权限约束。攻击者仍可构造 /user/999999 尝试越权。
- 永远对
ctx.Params("id")做非空和格式校验(如是否为数字、是否在合理范围内),防止空指针或 SQL 注入前置条件 - 不要用
strconv.Atoi(ctx.Params("id"))后直接拼 SQL;必须走参数化查询,并在校验归属后再执行主逻辑 - 若使用 ORM(如 GORM),注意
Where("user_id = ? AND id = ?", userID, id)这种写法虽能防越权,但前提是userID真实来自认证上下文,而非从请求里二次读取
配合 JWT 和 Redis 做更可靠的上下文绑定
仅靠中间件解析 Token 得到用户 ID 是不够的——Token 可能被复用、未及时失效。需要服务端主动管控会话生命周期。
- 登录成功后,生成 JWT 并将
tokenHash → userID+expireAt存入 Redis,设置与 Token 相同的过期时间 - 认证中间件中,先解析 JWT 获取 claim 中的
sub(用户 ID),再用 token 的 SHA256 值查 Redis,双校验通过才放行 - 登出或敏感操作(如改密码)时,立刻删掉 Redis 中对应 hash,实现 Token 主动失效
- 这样即使攻击者拿到有效 Token,只要服务端已将其标记为无效,后续所有带该 Token 的请求(包括越权请求)都会在中间件层被拦截,根本进不到业务 handler


















