说明
用户的数据永远是不可信的,要对客户端进入的数据进行验证后再使用。
三方库地址:thedevsaddam/govalidator
参考文档:thedevsaddam/govalidator#validation-rules
该项目借鉴了 PHP 的 Laravel,比较简单易用(好像停止维护了哎,一年没更新了)
安装
$ go get github.com/thedevsaddam/govalidator
基础使用 Demo
app/models/user/user.go:
package user
import "GoBlog/app/models"
// User 用户模型
type User struct {
models.BaseModel
Name string `gorm:"type:varchar(255);not null;unique" valid:"name"`
Email string `gorm:"type:varchar(255);unique" valid:"email"`
Password string `gorm:"type:varchar(255)" valid:"password"`
// gorm:"-" 设置 GORM 在读写时略过此字段
PasswordConfirm string `gorm:"-" valid:"password_confirm"`
}
app/requests/user_registration.go:
// ValidateRegistrationForm 验证表单,返回 errs 长度等于零即通过
func ValidateRegistrationForm(data user.User) url.Values {
// 1. 定制认证规则
rules := govalidator.MapData{
"name": []string{"required", "alpha_num", "between:3,20"},
"email": []string{"required", "min:4", "max:30", "email"},
"password": []string{"required", "min:6"},
"password_confirm": []string{"required"},
}
// 2. 定制错误信息
message := govalidator.MapData{
"name": []string{
"required:用户名为必填项",
"alpha_num:用户名格式错误,只允许数字和英文",
"between:用户名长度需在 3~20 之间",
},
"email": []string{
"required:邮箱为必填项",
"min:邮箱长度需大于 4",
"max:邮箱长度需小于 30",
"email:邮箱格式不正确,请提供有效的邮箱地址",
},
"password": []string{
"required:密码为必填项",
"min:密码长度需大于6",
},
"password_confirm": []string{
"required:确认密码框为必填项",
},
}
// 3. 配初始化
opts := govalidator.Options{
Data: &data,
Rules: rules,
TagIdentifier: "valid",
Messages: message,
}
// 4. 开始认证
errs := govalidator.New(opts).ValidateStruct()
if data.Password != data.PasswordConfirm {
errs["password_confirm"] = append(errs["password_confirm"], "两次输入的密码不匹配")
}
return errs
}
app/http/controllers/auth_controller.go:
// DoRegister 处理注册逻辑
func (*AuthController) DoRegister(w http.ResponseWriter, r *http.Request) {
// 1. 初始化数据
_user := user.User{
Name: r.PostFormValue("name"),
Email: r.PostFormValue("email"),
Password: r.PostFormValue("password"),
PasswordConfirm: r.PostFormValue("password_confirm"),
}
// 2. 表单规则
errs := requests.ValidateRegistrationForm(_user)
if len(errs) > 0 {
// 3. 有错误发生,打印数据
data, _ := json.MarshalIndent(errs, "", " ")
fmt.Fprint(w, string(data))
} else {
// 4. 验证成功,创建数据
err := _user.Create()
if _user.ID > 0 && err == nil {
fmt.Fprint(w, "插入成功,ID 为"+_user.GetStringID())
} else {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, "创建用户失败,请联系管理员")
}
}
}
创建自定义规则
参考文档:https://github.com/thedevsaddam/govalidator#add-custom-rules
app/requests/request.go:
// init 方法会在初始化时执行
func init() {
govalidator.AddCustomRule("not_exists", func(field string, rule string, message string, value interface{}) error {
rng := strings.Split(strings.TrimPrefix(rule, "not_exists:"), ",")
tableName := rng[0]
dbFiled := rng[1]
val := value.(string)
var count int64
model.DB.Table(tableName).Where(dbFiled+"= ?", val).Count(&count)
if count != 0 {
if message != "" {
return errors.New(message)
}
return fmt.Errorf("%v 已被占用", val)
}
return nil
})
}
在使用的时候可以在 roles 规则处加入 “not_exists:users,email”,例如:
rules := govalidator.MapData{
"name": []string{"required", "alpha_num", "between:3,20", "not_exists:users,name"},
"email": []string{"required", "min:4", "max:30", "email", "not_exists:users,email"},
"password": []string{"required", "min:6"},
"password_confirm": []string{"required"},
}
如上代码,其中的 not_exists 为我们新增的规则名称,users 为表名,email 为字段…
小提示:规则不同,用法不同,注意灵活多变
评论前必须登录!
注册