【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


相关文章
|
1月前
|
Go 索引
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
|
2月前
|
运维 监控 Go
Go语言微服务实战与最佳实践
【2月更文挑战第14天】本文将深入探讨使用Go语言进行微服务实战中的最佳实践,包括服务拆分、API设计、并发处理、错误处理、服务治理与监控等方面。通过实际案例和详细步骤,我们将分享如何在Go语言环境中构建高效、稳定、可扩展的微服务系统。
|
13天前
|
JSON 监控 安全
Golang深入浅出之-Go语言中的反射(reflect):原理与实战应用
【5月更文挑战第1天】Go语言的反射允许运行时检查和修改结构,主要通过`reflect`包的`Type`和`Value`实现。然而,滥用反射可能导致代码复杂和性能下降。要安全使用,应注意避免过度使用,始终进行类型检查,并尊重封装。反射的应用包括动态接口实现、JSON序列化和元编程。理解反射原理并谨慎使用是关键,应尽量保持代码静态类型。
25 2
|
15天前
|
JSON JavaScript 前端开发
Golang深入浅出之-Go语言JSON处理:编码与解码实战
【4月更文挑战第26天】本文探讨了Go语言中处理JSON的常见问题及解决策略。通过`json.Marshal`和`json.Unmarshal`进行编码和解码,同时指出结构体标签、时间处理、omitempty使用及数组/切片区别等易错点。建议正确使用结构体标签,自定义处理`time.Time`,明智选择omitempty,并理解数组与切片差异。文中提供基础示例及时间类型处理的实战代码,帮助读者掌握JSON操作。
23 1
Golang深入浅出之-Go语言JSON处理:编码与解码实战
|
1月前
|
前端开发 JavaScript Go
Go 实战|使用 Wails 构建轻量级的桌面应用:仿微信登录界面 Demo
Wails 框架提供了一种简洁而强大的方式,让开发者能够利用 Go 的性能优势和 Web 前端的灵活性,从而能够使用更高效、更轻量级的方法来构建跨平台的桌面应用。本文探讨 Wails 框架的使用,从搭建环境到开发,再到最终的构建打包。
47 1
Go 实战|使用 Wails 构建轻量级的桌面应用:仿微信登录界面 Demo
|
1月前
|
存储 安全 编译器
掌握Go语言:精通Go语言范围(range),高级应用及进销存系统实战(25)
掌握Go语言:精通Go语言范围(range),高级应用及进销存系统实战(25)
|
1月前
|
Go C语言 索引
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)
|
2月前
|
设计模式 缓存 安全
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
31 0
|
2月前
|
SQL 机器学习/深度学习 缓存
Go语言Web应用实战与案例分析
【2月更文挑战第21天】本文将通过实战案例的方式,深入探讨Go语言在Web应用开发中的应用。我们将分析一个实际项目的开发过程,展示Go语言在构建高性能、可扩展Web应用方面的优势,并分享在开发过程中遇到的问题和解决方案,为读者提供宝贵的实战经验。
|
2月前
|
关系型数据库 MySQL 数据库连接
实战演练:使用Go语言和ORM框架与数据库进行交互
【2月更文挑战第13天】本文将通过一个实战演练,展示如何使用Go语言和ORM(对象关系映射)框架与数据库进行交互。我们将选择一个流行的ORM框架,如GORM,来完成这个任务。通过实际编码,我们将演示如何连接数据库、执行CRUD操作、处理错误和异常,并展示ORM框架如何简化数据库操作过程。