作为后端开发者我们要记住一句话:“永远不要相信用户的输入”,这里所说的用户可能是人,也可能是另一个应用程序。“永远不要相信用户的输入”是安全编码的准则,也就是说,任何输入的内容在验证无害之前都是有害的。很多应用程序的安全漏洞都和用户输入有关,比如SQL注入漏洞。
验证非必填的邮箱字段
需求是这样的:我们需要验证一个字段可以为空,同时字段的值为合法的电子邮箱。
type MailRequest struct {
Email string `json:"email" binding:"email"` // 邮箱地址
}
requiredEmail必须是一个有效的邮箱omitemptyomitemptyomitempty
type MailRequest struct {
Email string `json:"email" binding:"omitempty,email"` // 邮箱地址
}
验证0值
先看代码
type AddRoleRequest struct {
Available int `json:"available" binding:"required"` // 是否可用 0 不可用 1 可用
}
AvailableintrequiredAvailable*int
type AddRoleRequest struct {
Available *int `json:"available" binding:"required"` // 是否可用 0 不可用 1 可用
}
自定义错误消息
前文基于gin的golang web开发:模型验证结尾部分,我们没有把参数验证的错误消息完全翻译成中文,字段名还是英文的。显然还有更优雅的做法,给用户提示一个更友好的错误信息。
{
"error": "Username为必填字段;"
}
Username
func init() {
translator := zh.New()
uni = ut.New(translator, translator)
trans, _ = uni.GetTranslator("zh")
validate := binding.Validator.Engine().(*validator.Validate)
// 注意这里
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
return fld.Tag.Get("display")
})
_ = zh_translations.RegisterDefaultTranslations(validate, trans)
}
func Translate(err error) string {
var result string
errors := err.(validator.ValidationErrors)
for _, err := range errors {
errMessage := err.Translate(trans)
result += errMessage + ";"
}
return result[:len(result)-1] //
validate.RegisterTagNameFuncdisplayTranslate
举个栗子
func checkUser(user string, password string) bool {
db := GetDbContext()
defer db.Close()
dataSql := `
select count(1) from sys_user
where username = '` + user + `' and password = '` + password + `'`
count := 0
log.Println(dataSql)
db.QueryRow(dataSql).Scan(&count)
return count > 0
}
1' or '1'='1dataSql
select count(1) from sys_user
where username = 'xxx' and password = '1' or '1'='1'
passwordalphanum1' or '1'='1
type UserAndPassword struct {
User string `json:"user" binding:"required,alphanum"`
Pwd string `json:"pwd" binding:"required,alphanum"`
}
func IsLoginIn(c *gin.Context) {
var req = UserAndPassword{}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.String(http.StatusOK, strconv.FormatBool(checkUser(req.User, req.Pwd)))
}
func checkUser(user string, password string) bool {
db := GetDbContext()
defer db.Close()
dataSql := `
select count(1) from sys_user
where username = '` + user + `' and password = '` + password + `'`
count := 0
log.Println(dataSql)
db.QueryRow(dataSql).Scan(&count)
return count > 0
}