# 登陆注册 ## 1.介绍 web中最基础的功能就是登陆注册,接下来我们利用gin实现一个简单的注册登陆功能。 ### 1.1.注册 注册的流程大致为: ``` 填写账号密码等信息->提交信息->服务端接收数据->参数校验->检查是否已经注册->密码加密->数据持久化到数据库->注册成功 ``` ### 1.2.登陆 登陆的流程大致为: ``` 填写账号密码等信息->提交信息->服务端接收数据->参数校验->检查账号密码是否正确->登陆成功 ``` ## 2.编码实现 - 新建模型,这里直接使用数据操作章节使用的User模型 ```go type User struct { ID uint `gorm:"primary_key"` Username string Password string } ``` - 新建一个UserDto,用于数据传输使用 dto/user_dto.go ```go package dto type UserDto struct { ID uint Username string Password string } ``` - 使用数据操作章节的user_repository.go作为数据操作 repositories/user/user_repository.go ```go package user import ( "cn.sockstack/gin_demo/dto" "cn.sockstack/gin_demo/models" ) //CreateUser 创建用户 func CreateUser(dto dto.UserDto) error { user := models.User{} user.Username = dto.Username user.Password = dto.Password err := models.DB.Create(&user).Error return err } //GetUserByUsername 通过用户名查询用户 func GetUserByUsername(username string) models.User { user := models.User{} models.DB.Find(&user, models.DB.Where("username = ?",username)) return user } //UpdateUser 更新用户信息 func UpdateUser(userDto dto.UserDto) error { user := models.User{} if userDto.Username != "" { user.Username = userDto.Username } if userDto.Password != "" { user.Password = userDto.Password } err := models.DB.Model(&user).Update(&user).Error return err } //DeleteUserById 通过Id删除用户 func DeleteUserById(id uint) error { err := models.DB.Delete(&models.User{ID: id}).Error return err } ``` - 用户接口 services/user/user_contract.go ```go package user import "cn.sockstack/gin_demo/dto" type UserContract interface { Register(dto dto.UserDto) error Login(dto dto.UserDto) error } ``` - 用户服务 services/user/user_service.go ```go package user import ( "cn.sockstack/gin_demo/dto" "cn.sockstack/gin_demo/pkg/hash" user2 "cn.sockstack/gin_demo/repositories/user" "errors" ) type UserService struct { } //Register 注册 func (user UserService) Register(userDto dto.UserDto) error { //密码加密 bytes, err := hash.NewHash().Make([]byte(userDto.Password)) if err != nil { return errors.New(err.Error()) } userDto.Password = string(bytes) return user2.CreateUser(userDto) } //Login 登陆 func (user UserService)Login(userDto dto.UserDto) error { model := user2.GetUserByUsername(userDto.Username) if model.ID == 0 { return errors.New("账号不存在") } err := hash.NewHash().Check([]byte(model.Password), []byte(userDto.Password)) if err != nil { return errors.New("密码错误") } return nil } ``` - 登陆注册入参定义 requests/v1/user.go ```go package v1 //RegisterRequest 注册入参 type RegisterRequest struct { Username string `form:"username" binding:"required"` Password string `form:"password" binding:"required"` } //LoginRequest 登陆入参 type LoginRequest struct { Username string `form:"username" binding:"required"` Password string `form:"password" binding:"required"` } ``` - 用户控制器 api/user/v1/user.go ```go package v1 import ( "cn.sockstack/gin_demo/dto" "cn.sockstack/gin_demo/pkg/e" v1 "cn.sockstack/gin_demo/requests/v1" "cn.sockstack/gin_demo/services/user" "github.com/gin-gonic/gin" ) //RegisterHandle 注册 func RegisterHandle(c *gin.Context) (interface{}, error) { request := v1.RegisterRequest{} err := c.ShouldBind(&request) if err != nil { return nil, e.ApiError{ Status: 422, Code: 40004, Message: "参数校验失败", Data: err, } } userDto := dto.UserDto{ Username: request.Username, Password: request.Password, } service := user.UserService{} err = service.Register(userDto) if err != nil { return nil, e.ApiError{ Status: 422, Code: 40005, Message: err.Error(), } } return "注册成功", nil } //LoginHandle 登陆 func LoginHandle(c *gin.Context) (interface{}, error) { request := v1.LoginRequest{} err := c.ShouldBind(&request) if err != nil { return nil, e.ApiError{ Status: 422, Code: 40004, Message: "参数校验失败", Data: err, } } userDto := dto.UserDto{ Username: request.Username, Password: request.Password, } service := user.UserService{} err = service.Login(userDto) if err != nil { return nil, e.ApiError{ Status: 422, Code: 40005, Message: err.Error(), } } return "登陆成功", nil } ``` - 定义路由 routers/v1/user.go ```go package v1 import ( v1 "cn.sockstack/gin_demo/api/v1" "cn.sockstack/gin_demo/pkg/e" "github.com/gin-gonic/gin" ) func UserRouter(r *gin.Engine) { //注册 r.POST("/register", e.ErrorWrapper(v1.RegisterHandle)) //登陆 r.POST("/login", e.ErrorWrapper(v1.LoginHandle)) } ``` ## 3.总结 这个简单的例子中,使用了前面学到的所有知识点,比较简单,但是可以基于该例子整合其他功能,类型:验证码,限流,jwt等。 > 更多内容请关注我的博客[SOCKSTACk](https://www.sockstack.cn)