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

简介: 文章目录1. 路由注册2. 接口编写2.1 service层2.2 api层2.3 service3. 登陆测试

文章目录

1. 路由注册

2. 接口编写

2.1 service层

2.2 api层

2.3 service

3. 登陆测试

1. 路由注册

定义一个用户登录路由

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


2. 接口编写

2.1 service层

定义用户登录的服务结构

//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 {
  ...
}


2.2 api层

定义用户登录的服务

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)
  }
}


2.3 service

查询用户是否存在

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),
  }
}

3. 登陆测试

image.png


相关文章
|
2月前
|
Shell Go API
Go语言grequests库并发请求的实战案例
Go语言grequests库并发请求的实战案例
|
2月前
|
安全 大数据 Go
深入探索Go语言并发编程:Goroutines与Channels的实战应用
在当今高性能、高并发的应用需求下,Go语言以其独特的并发模型——Goroutines和Channels,成为了众多开发者眼中的璀璨明星。本文不仅阐述了Goroutines作为轻量级线程的优势,还深入剖析了Channels作为Goroutines间通信的桥梁,如何优雅地解决并发编程中的复杂问题。通过实战案例,我们将展示如何利用这些特性构建高效、可扩展的并发系统,同时探讨并发编程中常见的陷阱与最佳实践,为读者打开Go语言并发编程的广阔视野。
|
3月前
|
消息中间件 缓存 Kafka
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
|
3月前
|
缓存 NoSQL Redis
go-zero微服务实战系列(七、请求量这么高该如何优化)
go-zero微服务实战系列(七、请求量这么高该如何优化)
|
3月前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
3月前
|
消息中间件 NoSQL Kafka
go-zero微服务实战系列(九、极致优化秒杀性能)
go-zero微服务实战系列(九、极致优化秒杀性能)
|
3月前
|
消息中间件 缓存 监控
go-zero微服务实战系列(六、缓存一致性保证)
go-zero微服务实战系列(六、缓存一致性保证)
|
6天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
23 2
|
4天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
13 2
|
4天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
16 2