摒弃世俗浮躁
追求技术精湛

Golang笔记(八):表单验证

说明

用户的数据永远是不可信的,要对客户端进入的数据进行验证后再使用。
三方库地址: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 为字段…

小提示:规则不同,用法不同,注意灵活多变
赞(0) 打赏
未经允许不得转载:时光日记 » Golang笔记(八):表单验证

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册