这是我参与「第五届青训营 」伴学笔记创作活动的第 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)