文章目录
1. 编写路由
2. 注册路由
3. 注册接口
3.1 service层
3.2 api层
3.2 serializer
4. 注册服务
用到的包
github.com/gin-contrib/sessions
github.com/gin-contrib/sessions/cookie
github.com/gin-gonic/gin
1. 编写路由
新建一个WSGI应用程序实例。
r := gin.Default()
设置全局变量store
store := cookie.NewStore([]byte("something-very-secret"))
在路由中使用中间件调用store
r.Use(sessions.Sessions("mysession", store))
2. 注册路由
分一个基础路由组
v1 := r.Group("api/v1")
在这个基础路由编写用户注册路由
v1 := r.Group("api/v1") { //用户操作 v1.POST("user/register", api.UserRegister) }
3.1 service层
在service先创建一个user.go
再在service层上编写用户注册服务的结构体
//UserRegisterService 管理用户注册服务 type UserRegisterService struct { Nickname string `form:"nickname" json:"nickname" binding:"required,min=2,max=10"` UserName string `form:"user_name" json:"user_name" binding:"required,min=5,max=15"` Password string `form:"password" json:"password" binding:"required,min=8,max=16"` }
在service上编写用户注册register方法
func (service *UserRegisterService) Register() { }
3.2 api层
在api层创建user.go
申请一个 UserRegisterService用户注册服务对象。
var userRegisterService service.UserRegisterService
但是这个服务我们还没有写,先把这个接口写完,再把这个服务补上。
上下文绑定数据
c.ShouldBind(&userRegisterService)
调用这个服务的register方法
res := userRegisterService.Register()
返回这个服务的处理结果
c.JSON(200, res)
api 层的用户注册服务全部代码
func UserRegister(c *gin.Context) { var userRegisterService service.UserRegisterService //相当于创建了一个UserRegisterService对象 if err := c.ShouldBind(&userRegisterService); err == nil { res := userRegisterService.Register() //调用这个对象中的Register方法。 c.JSON(200, res) } else { c.JSON(200, ErrorResponse(err)) logging.Info(err) } }
创建一个common.go文件, 进行错误的返回
//返回错误信息 ErrorResponse func ErrorResponse(err error) serializer.Response { if ve, ok := err.(validator.ValidationErrors); ok { for _, e := range ve { field := conf.T(fmt.Sprintf("Field.%s", e.Field)) tag := conf.T(fmt.Sprintf("Tag.Valid.%s", e.Tag)) return serializer.Response{ Status: 40001, Msg: fmt.Sprintf("%s%s", field, tag), Error: fmt.Sprint(err), } } } if _, ok := err.(*json.UnmarshalTypeError); ok { return serializer.Response{ Status: 40001, Msg: "JSON类型不匹配", Error: fmt.Sprint(err), } } return serializer.Response{ Status: 40001, Msg: "参数错误", Error: fmt.Sprint(err), } }
3.2 serializer
创建一个基础的序列化返回结构体
// Response 基础序列化器 type Response struct { Status int `json:"status"` Data interface{} `json:"data"` Msg string `json:"msg"` Error string `json:"error"` }
4. 注册服务
接下来我们就可以编写register()注册服务了
先对传过来的用户名进行验证,查看是否已经存在了
model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count) if count == 1 { code = e.ErrorExistUser return serializer.Response{ Status: code, Msg: e.GetMsg(code), } }
再对密码进行加密
if err := user.SetPassword(service.Password); err != nil { logging.Info(err) code = e.ErrorFailEncryption return serializer.Response{ Status: code, Msg: e.GetMsg(code), } }
注意: 我们可以直接再model/user.go下编写密码加密方法
const ( PassWordCost = 12 //密码加密难度 Active string = "active" //激活用户 ) //SetPassword 设置密码 func (user *User) SetPassword(password string) error { bytes, err := bcrypt.GenerateFromPassword([]byte(password), PassWordCost) if err != nil { return err } user.PasswordDigest = string(bytes) return nil }
确认无误之后对用户进行创建
if err := model.DB.Create(&user).Error; err != nil { logging.Info(err) code = e.ErrorDatabase return serializer.Response{ Status: code, Msg: e.GetMsg(code), } }
服务层中用户注册的完整代码
func (service *UserRegisterService) Register() serializer.Response { var user model.User var count int code := e.SUCCESS model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count) if count == 1 { code = e.ErrorExistUser return serializer.Response{ Status: code, Msg: e.GetMsg(code), } } user = model.User{ Nickname: service.Nickname, UserName: service.UserName, Status: model.Active, } //加密密码 if err := user.SetPassword(service.Password); err != nil { logging.Info(err) code = e.ErrorFailEncryption return serializer.Response{ Status: code, Msg: e.GetMsg(code), } } user.Avatar = "http://q1.qlogo.cn/g?b=qq&nk=294350394&s=640" //创建用户 if err := model.DB.Create(&user).Error; err != nil { logging.Info(err) code = e.ErrorDatabase return serializer.Response{ Status: code, Msg: e.GetMsg(code), } } return serializer.Response{ Status: code, Msg: e.GetMsg(code), } }
下一章中,我们编写用户登录的业务逻辑。