【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


相关文章
|
14天前
|
安全 大数据 Go
深入探索Go语言并发编程:Goroutines与Channels的实战应用
在当今高性能、高并发的应用需求下,Go语言以其独特的并发模型——Goroutines和Channels,成为了众多开发者眼中的璀璨明星。本文不仅阐述了Goroutines作为轻量级线程的优势,还深入剖析了Channels作为Goroutines间通信的桥梁,如何优雅地解决并发编程中的复杂问题。通过实战案例,我们将展示如何利用这些特性构建高效、可扩展的并发系统,同时探讨并发编程中常见的陷阱与最佳实践,为读者打开Go语言并发编程的广阔视野。
|
1天前
|
Shell Go API
Go语言grequests库并发请求的实战案例
Go语言grequests库并发请求的实战案例
|
25天前
|
消息中间件 缓存 Kafka
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
|
25天前
|
缓存 NoSQL Redis
go-zero微服务实战系列(七、请求量这么高该如何优化)
go-zero微服务实战系列(七、请求量这么高该如何优化)
|
24天前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
24天前
|
消息中间件 NoSQL Kafka
go-zero微服务实战系列(九、极致优化秒杀性能)
go-zero微服务实战系列(九、极致优化秒杀性能)
|
25天前
|
消息中间件 缓存 监控
go-zero微服务实战系列(六、缓存一致性保证)
go-zero微服务实战系列(六、缓存一致性保证)
|
Go
Go实战(一)-概述
Go实战(一)-概述
105 0
Go实战(一)-概述
|
10天前
|
程序员 Go PHP
为什么大部分的 PHP 程序员转不了 Go 语言?
【9月更文挑战第8天】大部分 PHP 程序员难以转向 Go 语言,主要因为:一、编程习惯与思维方式差异,如语法风格和编程范式;二、学习成本高,需掌握新知识体系且面临项目压力;三、职业发展考量,现有技能价值及市场需求不确定性。学习新语言虽有挑战,但对拓宽职业道路至关重要。
40 10
|
8天前
|
Go API 开发者
深入探讨:使用Go语言构建高性能RESTful API服务
在本文中,我们将探索Go语言在构建高效、可靠的RESTful API服务中的独特优势。通过实际案例分析,我们将展示Go如何通过其并发模型、简洁的语法和内置的http包,成为现代后端服务开发的有力工具。