You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:35:21