iris 中应优先使用 readjson + 结构体 binding 标签进行请求体校验,并为 app.validator 赋值 validator 实例;路由参数用 {id:uint64} 等宏在匹配阶段拦截非法值;查询和表单参数需手动校验;中间件中校验失败必须调 ctx.stopexecution() 中断执行。

用 ReadJSON + 结构体标签做基础校验
直接绑定请求体并验证字段,比一个个调 ctx.FormValue 或 ctx.Params().Get 更安全、更可维护。Iris 内置支持 ReadJSON、ReadForm、ReadQuery 等方法,配合结构体 tag 就能触发自动校验。
关键点是:必须给 app.Validator 赋值一个 validator 实例(比如 go-playground/validator/v10),否则 binding 标签会被忽略。
-
binding:"required"表示字段不能为空(空字符串、零值都算无效) -
binding:"email"会检查格式是否符合邮箱规范 -
binding:"gte=18,lte=120"限制整数范围,对Age int这类字段很实用 - JSON 字段名映射靠
json:"field_name",别漏写,否则绑定失败
示例:
type User struct {
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
Age int `json:"age" binding:"gte=0,lte=150"`
}
func handler(ctx iris.Context) {
var u User
if err := ctx.ReadJSON(&u); err != nil {
ctx.StatusCode(400)
ctx.WriteString(err.Error())
return
}
// u 已通过校验,可放心使用
}
ctx.Params() 的宏约束在路由层拦截非法值
路径参数(如 /user/{id:uint64})的校验不能只靠运行时转换——得在匹配阶段就卡住非法输入,避免 handler 被调用。Iris 支持在路由定义里嵌入类型宏和自定义规则,这是最轻量也最有效的第一道防线。
-
{id:uint64}:非数字或负数、超范围值直接 404,不进 handler -
{oid:int min(1) max(999999)}:注册自定义宏后,0或1000000请求根本不会命中该路由 -
{path:path}:捕获完整子路径,但注意它不做 URL 解码,%20仍为原始编码,需手动调url.PathUnescape - 大小写敏感:
{ID}和{id}是两个不同参数名,匹配失败时静默返回空字符串,容易漏判
ctx.URLParam() 和 ctx.FormValue() 需手动校验
查询参数(?page=2&sort=name)和表单字段(application/x-www-form-urlencoded)不走结构体绑定,默认无校验能力,必须自己检查空值、类型、范围。
-
ctx.URLParam("page")返回string,要转int得用strconv.Atoi或ctx.URLParamIntDefault("page", 1) -
ctx.FormValue("email")同理,建议封装成带默认值和错误 fallback 的工具函数 - 别依赖
len(ctx.FormValue("email")) > 0判空——用户可能提交空格或" ",应先strings.TrimSpace - 如果同时有 query 和 form 提交(比如 POST 带 query 参数),注意两者取值逻辑独立,别混用
中间件里提前校验并中断执行
全局性参数检查(如 token 校验、权限判断)适合放在中间件里做,但必须显式调用 ctx.StopExecution(),否则 ctx.Next() 仍会往下走,导致重复处理或越权操作。
- JWT 中间件验证失败后,
ctx.StatusCode(401)+ctx.JSON(...)之后必须跟ctx.StopExecution() - 自定义鉴权中间件中,若
ctx.Params().Get("tenant") == "",应立即响应并中断,而不是让业务 handler 自己去判 - 不要在中间件里用
return代替ctx.StopExecution()——return只退出当前函数,不影响后续 handler 执行 - 多个中间件串联时,前一个没中断,后一个的校验就可能白做;顺序很重要,校验类中间件应尽量靠前
路径参数宏校验和结构体绑定是两套互补机制:前者守门,后者兜底。真正容易被忽略的是——当用 {id:uint64} 时,ctx.Params().GetUint64("id") 调用不再需要检查 err,但很多人还是习惯性加 if err != nil,反而掩盖了其他潜在问题。











