【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


相关文章
|
8月前
|
Linux Go iOS开发
Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
1331 162
|
8月前
|
存储 前端开发 JavaScript
Go语言实战案例-项目实战篇:编写一个轻量级在线聊天室
本文介绍如何用Go语言从零实现一个轻量级在线聊天室,基于WebSocket实现实时通信,支持多人消息广播。涵盖前后端开发、技术选型与功能扩展,助你掌握Go高并发与实时通信核心技术。
888 158
|
9月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
934 0
|
9月前
|
数据采集 Go API
Go语言实战案例:使用context控制协程取消
本文详解 Go 语言中 `context` 包的使用,通过实际案例演示如何利用 `context` 控制协程的生命周期,实现任务取消、超时控制及优雅退出,提升并发程序的稳定性与资源管理能力。
488 152
|
9月前
|
负载均衡 监控 Java
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
在微服务架构中,高可用与稳定性至关重要。本文详解熔断、限流与负载均衡三大关键技术,结合API网关与Hystrix-Go实战,帮助构建健壮、弹性的微服务系统。
876 1
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
|
9月前
|
安全 Go 开发者
Go语言实战案例:使用sync.Mutex实现资源加锁
在Go语言并发编程中,数据共享可能导致竞态条件,使用 `sync.Mutex` 可以有效避免这一问题。本文详细介绍了互斥锁的基本概念、加锁原理及实战应用,通过构建并发安全的计数器演示了加锁与未加锁的区别,并封装了一个线程安全的计数器结构。同时对比了Go中常见的同步机制,帮助开发者理解何时应使用 `Mutex` 及其注意事项。掌握 `Mutex` 是实现高效、安全并发编程的重要基础。
|
9月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
中间件 API Go
【Go实战 | 电商平台】(4) 用户注册
文章目录 1. 编写路由 2. 注册路由 3. 注册接口 3.1 service层 3.2 api层 3.2 serializer 4. 注册服务 用到的包
329 0
【Go实战 | 电商平台】(4) 用户注册
|
7月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
374 2
|
9月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
566 1

热门文章

最新文章