项目笔记(5)——重复注册校验 | 青训营笔记

104 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天

一、重复注册校验

在models中的userbasic中添加重复校验注册的方法。
方法逻辑:首先定义一个user变量让它获得数据库中的所有字段,然后再使用建立数据库的utils包,调用DB后对数据库进行Where的查询,类似于c语言的写法,用?代替变量的位置,然后使用First表示按该结构体的第一个字段进行查找。

func FindUserByNameAndPwd(name string , password string) UserBasic{
	user := UserBasic{}
	utils.DB.Where("name = ? and password = ?",name,password).First(&user)
	return user
}

func FindUserByName(name string) UserBasic{
	user := UserBasic{}
	utils.DB.Where("name = ?",name).First(&user) //这里的First是指从数据库中获取到的第一个字段
	return user
}

func FindUserByPhone(phone string) *gorm.DB{
	user := UserBasic{}
	return utils.DB.Where("phone = ?",phone).First(&user)	
}

func FindUserByEmail(email string) *gorm.DB{
	user := UserBasic{}
	return utils.DB.Where("email = ?",email).First(&user)	
}

二、加密操作

在utils包中创建一个新的文件,命名为md5.go,然后引入包"crypto/md5"。此处实现了最简单的加密方法——小写、大写、加密、解密。注意,此处引入了随机数salt,那么相应的要在数据库中添加上这个字段,以便后续使用密码的校验和查询。

package utils

import (
	"crypto/md5"
	"encoding/hex"
	"strings"
)

// md5工具类--加密为小写
func md5Encode(data string) string {
	h:=md5.New()
	h.Write([]byte(data))
	tempStr := h.Sum(nil)
	return hex.EncodeToString(tempStr)//将十进制数转换成十六进制
}

// 大写
func MD5Encode(data string) string {
	return strings.ToUpper(md5Encode(data))
} 

// 加密
func MakePassword(plainpwd, salt string) string {
	return md5Encode(plainpwd+salt)
}

// 解密
func ValidPassword(plainpwd, salt string, password string) bool {
	return md5Encode(plainpwd + salt) == password
}

以上在MD5文件中将各个方法完成后,就在userservice中的createUser完成对密码的加密。

salt := fmt.Sprintf("%06d",rand.Int31()) //产生随机数进行加密
user.Password = utils.MakePassword(password,salt) //将原始输入框的密码和随机数进行结合,产生一个加密密码
user.Salt = salt //将随机数写入user,以便create时写入数据库中的字段

注意,在创建好的数据库表之后,若需要添加新的字段,首先在testgorm里将下面创建数据库的代码注释掉,然后重新启动,关键的更新代码为 db.AutoMigrate(&models.UserBasic{})

三、登陆解密

功能描述:
这个功能实现的关键是读取用户名和密码,然后通过查找返回一个具体的用户字段信息。
实现思路:
name和password是用户传递进来的参数,那么首先按照姓名进行查询,调用models.FindUserByName,查看用户是否存在,若不存在直接返回,拿到存在的用户便于后续对其余字段的一个调用。接着对密码进行解密,调用在utils包中实现的解密方法,将三个参数传递进去,从而判断密码是否正确。若正确,那么就对密码进行加密,用于匹配该用户数据库中的密码,匹配完成后,最后将这两个变量传入写好的方法中,用于对用户信息的查询。
总结:
判断是否存在该用户,拿到数据库中的一个用户字段——>判断数据库中的密码解密后是否与输入框中传入的参数一致——>一致对传入的密码进行加密,然后调用方法进行查询

dao层(models)
func FindUserByNameAndPwd(name string , password string) UserBasic{
	user := UserBasic{}
	utils.DB.Where("name = ? and password = ?",name,password).First(&user)
	return user
}

service层:
// FindUser
// @Summary 查询用户
// @Tags 用户模块
// @param name query string false "用户名"
// @param password query string false "密码"
// @Success 200 {string} json{"code","message"}
// @Router /user/findUserByNameAndPwd [post]
func FindUserByNameAndPwd(c *gin.Context) {
	data := models.UserBasic{}
	name := c.Query("name")
	password := c.Query("password")
	user := models.FindUserByName(name)
	fmt.Println(user)
	if user.Name == ""{
		c.JSON(200, gin.H{
			"message": "该用户不存在!",
		})		
		return //只要有不正确的地方,那么就直接返回结束即可
	}
	flag := utils.ValidPassword(password,user.Salt,user.Password)
	if !flag {
		c.JSON(200, gin.H{
			"message": "密码不正确!",
		})	
		return 
	}
	pwd := utils.MakePassword(password,user.Salt)
	data = models.FindUserByNameAndPwd(name,pwd)
	c.JSON(200,gin.H{
		"message":data,
	})
}

router层
r.POST("/user/findUserByNameAndPwd",service.FindUserByNameAndPwd)