Golang Gin框架如何禁止请求体携带额外字段?
解决JSON请求体额外字段存入数据库的问题
问题本质
github.com/go-playground/validator/v10 仅负责校验结构体已有字段的规则(如必填、格式合法性),不会处理"禁止客户端传入特定字段"或"拦截未知字段"的需求。你遇到的id:111被存入数据库,是因为id属于gorm.Model中的ID字段,反序列化时会被赋值到结构体,最终被GORM写入数据库。
解决方案
方案1:屏蔽gorm.Model字段的JSON反序列化
直接把gorm.Model的字段展开,给不需要客户端传入的字段设置json:"-"标签,这样JSON反序列化时会忽略这些字段,客户端传入的id、created_at等不会被赋值到结构体:
import ( "time" "gorm.io/gorm" ) type User struct { ID uint `gorm:"primarykey" json:"-"` CreatedAt time.Time `json:"-"` UpdatedAt time.Time `json:"-"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` Username string `json:"username" validate:"required" gorm:"unique"` Email string `json:"email" validate:"required,email" gorm:"unique"` Password string `json:"password" validate:"required"` }
方案2:验证ID字段必须为0(拦截非法传入ID)
如果需要在客户端传入ID时直接报错,保留gorm.Model并给ID字段添加validate:"eq=0"规则(数据库自增ID在插入前的零值为0):
type User struct { gorm.Model Username string `json:"username" validate:"required" gorm:"unique"` Email string `json:"email" validate:"required,email" gorm:"unique"` Password string `json:"password" validate:"required"` }
验证时直接检查:
validate := validator.New() err := validate.Struct(user) if err != nil { // 返回错误给客户端,提示非法传入ID return }
方案3:反序列化时拒绝未知字段(拦截结构体未定义的字段)
如果要阻止客户端传入age这类结构体完全没有的字段,在JSON反序列化时使用DisallowUnknownFields(),遇到未知字段直接报错:
var user User decoder := json.NewDecoder(r.Body) // 禁止反序列化未知字段 decoder.DisallowUnknownFields() err := decoder.Decode(&user) if err != nil { // 返回错误,提示传入了无效字段 return } // 再执行原有字段规则校验 validate := validator.New() err = validate.Struct(user)
内容的提问来源于stack exchange,提问作者Syed Ashraf
相关产品推荐
相关产品推荐

