Go使用struct validator:如何通过内置验证禁止请求体含特定字段
关于go-playground/validator禁止特定字段传入的问题
go-playground/validator 目前没有内置规则可以直接实现“禁止请求体包含特定字段”的校验需求。这个库的内置规则主要聚焦于字段值的格式、范围、合法性等校验,而非判断字段是否存在于请求中。
不过可以通过以下两种方式实现你的需求:
方案1:自定义验证器(推荐)
结合指针类型区分“字段未传入”和“字段传入空值”的场景,再编写自定义验证规则:
- 修改结构体,将
Type字段改为指针类型:
type ClientPhone struct { ID uuid.UUID `json:"id"` CountryCode string `json:"countryCode" validate:"omitempty,min=2,max=3,number"` PhoneNumber string `json:"phoneNumber" validate:"omitempty,number,len=10"` Type *string `json:"type" validate:"forbidden"` }
- 注册并实现自定义验证函数:
// forbiddenField 验证字段是否被禁止传入 func forbiddenField(fl validator.FieldLevel) bool { // 若字段指针不为nil,说明请求体包含了该字段,返回false触发验证错误 return fl.Field().IsNil() } // 初始化验证器时注册规则 v := validator.New() if err := v.RegisterValidation("forbidden", forbiddenField); err != nil { // 处理注册错误 }
当请求体中包含type字段时(无论值是否为空),指针都会被初始化,验证函数返回false,触发验证错误。
方案2:解析前检查请求体
如果不想修改结构体类型,可以先将请求体解析为原始map,提前检查字段是否存在:
import ( "encoding/json" "io" "net/http" "strings" ) func handlePatchRequest(w http.ResponseWriter, r *http.Request) { // 先读取请求体内容 bodyBytes, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "invalid request body", http.StatusBadRequest) return } // 重新封装请求体供后续解码使用 r.Body = io.NopCloser(strings.NewReader(string(bodyBytes))) // 解析为原始map检查字段 var rawData map[string]interface{} if err := json.Unmarshal(bodyBytes, &rawData); err != nil { http.Error(w, "invalid request body", http.StatusBadRequest) return } if _, hasType := rawData["type"]; hasType { http.Error(w, "field 'type' is not allowed in patch request", http.StatusBadRequest) return } // 解码到目标结构体 var clientPhone ClientPhone if err := json.NewDecoder(r.Body).Decode(&clientPhone); err != nil { http.Error(w, "invalid request body", http.StatusBadRequest) return } // 后续业务逻辑处理 }
内容的提问来源于stack exchange,提问作者Asitha
相关产品推荐
相关产品推荐

