参考视频:
上一篇:(1条消息) Gin+Gorm+PostGresSQL+Vue项目实战(4)_代码骑士的博客-CSDN博客
回顾:使用 jwt 发放 token 使用 gin 的中间件写一个用户认证的中间件保护路由并实现用户认证。
本期:隐藏返回时的敏感字段,并将请求返回进行统一封装。
一、请求返回的封装
1、隐藏敏感字段
新建dto文件夹并创建user_dto.go文件:
package dto
import "testGinAndVue01/model"
type UserDto struct {
Name string `json:"name,omitempty"`
Telephone string `json:"telephone,omitempty"`
}
func ToUserDto(user model.User) UserDto {
return UserDto{
Name: user.Name,
Telephone: user.Telephone,
}
}
在usercontroller.go里面修改代码Info函数:
//用户信息
func Info(ctx *gin.Context) {
user, _ := ctx.Get("user")
ctx.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": dto.ToUserDto(user.(model.User))}})
}
测试:
只显示名字和电话号码:
2、统一封装请求返回
新建文件夹response和文件response.go
response.go
package response
import (
"net/http"
"github.com/gin-gonic/gin"
)
/*返回值的一般形式
{
code: xxx(int)
data: xxx(string)
msg: xxx(string)
}
*/
func Response(ctx *gin.Context, httpStatus int, code int, data gin.H, msg string) { //httpStatus:标准状态码 ;code:业务状态码
ctx.JSON(httpStatus, gin.H{"code": code, "data": data, "msg": msg})
}
func Success(ctx *gin.Context, data gin.H, msg string) {
Response(ctx, http.StatusOK, 200, data, msg)
}
func Faile(ctx *gin.Context, data gin.H, msg string) {
Response(ctx, http.StatusOK, 400, data, msg)
}
修改usercontroller.go
package controller
import (
"log"
"net/http"
"testGinAndVue01/common"
"testGinAndVue01/dto"
"testGinAndVue01/model"
"testGinAndVue01/response"
"testGinAndVue01/util"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
//"gorm.io/gorm"
)
//注册
func Register(ctx *gin.Context) {
//db := common.InitDB()
db := common.GetDB()
//获取参数
name := ctx.PostForm("name")
telephone := ctx.PostForm("telephone")
password := ctx.PostForm("password")
//数据验证
if len(telephone) != 11 {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号必须是11位")
return
}
if len(password) < 6 {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "密码至少6位")
return
}
//如果名称为空值就随机生成十位字符串
if len(name) == 0 {
name = util.RandomString(10)
}
log.Println(name, telephone, password)
//判断手机号是否存在
if isTelephoneExist_(telephone) {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "该手机号已被注册")
return
}
//创建用户
hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) //进行密码加密
if err != nil {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "加密错误")
return
}
newUser := model.User{
Name: name,
Telephone: telephone,
Password: string(hasedPassword),
}
db.Create(&newUser)
//返回结果
response.Success(ctx, nil, "注册成功")
}
func isTelephoneExist_(telephone string) bool {
var user model.User
db := common.GetDB()
db.Where("telephone=?", telephone).First(&user)
if user.ID != 0 {
return true
} else {
return false
}
}
//登录
func Login(ctx *gin.Context) {
//获取参数
telephone := ctx.PostForm("telephone")
password := ctx.PostForm("password")
//数据验证
if len(telephone) != 11 {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号必须是11位")
return
}
if len(password) < 6 {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "密码至少6位")
return
}
//判断用户是否注册过
var user model.User
DB := common.GetDB()
if isTelephoneExist_(telephone) {
//判断密码是否正确
DB.Where("telephone=?", telephone).First(&user)
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
response.Response(ctx, http.StatusUnprocessableEntity, 400, nil, "密码错误")
return
} else {
//发放token给前端
token, err := common.ReleaseToken(user)
if err != nil {
response.Response(ctx, http.StatusUnprocessableEntity, 500, nil, "系统异常")
log.Printf("token generate error:%v", err)
return
}
//返回结果
response.Success(ctx, gin.H{"token": token}, "登录成功")
}
} else {
response.Response(ctx, http.StatusUnprocessableEntity, 422, nil, "该用户不存在")
return
}
}
//用户信息
func Info(ctx *gin.Context) {
user, _ := ctx.Get("user")
ctx.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": dto.ToUserDto(user.(model.User))}})
}
3、演示
下一篇: