天天看点

【Go实战 | 电商平台】(5) 用户登录

文章目录

1. 路由注册

2. 接口编写

2.1 service层

2.2 api层

2.3 service

3. 登陆测试

定义一个用户登录路由

v1.POST("user/login", api.UserLogin)      

定义用户登录的服务结构

//UserLoginService 管理用户登陆的服务
type UserLoginService struct {
    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"`
}      

编写用户登录的服务方法

func (service *UserLoginService) Login() serializer.Response {
    ...
}      

定义用户登录的服务

var userLoginService service.UserLoginService      

绑定数据

运行userLoginService对象的login方法

res := userLoginService.Login()      

用户登录的接口函数返回

c.JSON(200, res)      

用户登录接口的完整代码

func UserLogin(c *gin.Context) {
    var userLoginService service.UserLoginService
    if err := c.ShouldBind(&userLoginService); err == nil {
  res := userLoginService.Login()
  c.JSON(200, res)
    } else {
  c.JSON(400, ErrorResponse(err))
  logging.Info(err)
    }
}      

查询用户是否存在

if err := model.DB.Where("user_name=?", service.UserName).First(&user).Error; err != nil {
  //如果查询不到,返回相应的错误
  if gorm.IsRecordNotFoundError(err) {
    logging.Info(err)
    code = e.ErrorNotExistUser
    return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
    }
  }
  logging.Info(err)
  code = e.ErrorDatabase
  return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
  }
    }      

在model/user下进行密码

//CheckPassword 校验密码
func (user *User) CheckPassword(password string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(user.PasswordDigest), []byte(password))
    return err == nil
}      

验证用户密码

if user.CheckPassword(service.Password) == false {
  code = e.ErrorNotCompare
  return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
  }
    }      

给用户签发token

token, err := util.GenerateToken(service.UserName, service.Password, 0)      

定义claims的结构体

type Claims struct {
    ID     uint  `json:"id"`
    Username  string `json:"username"`
    Authority int    `json:"authority"`
    jwt.StandardClaims
}      

生成token函数

我们传入用户的id,username和password以及authority权限加密成token,后续就可以进行身份的验证
func GenerateToken(id uint ,username, password string, authority int) (string, error) {
    nowTime := time.Now()
    expireTime := nowTime.Add(24 * time.Hour)
    claims := Claims{
  Username:  username,
  Password:  password,
  Authority: authority,
  StandardClaims: jwt.StandardClaims{
    ExpiresAt: expireTime.Unix(),
    Issuer:    "cmall",
  },
    }
    tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    token, err := tokenClaims.SignedString(jwtSecret)
    return token, err
}      

用户登录服务的完整代码

func (service *UserLoginService) Login() serializer.Response {
    var user model.User
    code := e.SUCCESS
    if err := model.DB.Where("user_name=?", service.UserName).First(&user).Error; err != nil {
  //如果查询不到,返回相应的错误
  if gorm.IsRecordNotFoundError(err) {
    logging.Info(err)
    code = e.ErrorNotExistUser
    return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
    }
  }
  logging.Info(err)
  code = e.ErrorDatabase
  return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
  }
    }
    if user.CheckPassword(service.Password) == false {
  code = e.ErrorNotCompare
  return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
  }
    }
    token, err := util.GenerateToken(user.ID, service.UserName, 0)
    if err != nil {
  logging.Info(err)
  code = e.ErrorAuthToken
  return serializer.Response{
    Status: code,
    Msg:    e.GetMsg(code),
  }
    }
    return serializer.Response{
  Status: code,
  Data:   serializer.TokenData{User: serializer.BuildUser(user), Token: token},
  Msg:    e.GetMsg(code),
    }
}      
【Go实战 | 电商平台】(5) 用户登录