Go Web 开发 Demo【用户登录、注册、验证】(1)

简介: Go Web 开发 Demo【用户登录、注册、验证】

前言

       这篇文章主要是学习怎么用 Go 语言(Gin)开发Web程序,前端太弱了,得好好补补课,完了再来更新。

1、环境准备

新建项目,生成 go.mod 文件:

出现报错:go: modules disabled by GO111MODULE=off; see 'go help modules',说明需要开启:

临时设置环境变量

set GO111MODULE=on # windows
export GO111MODULE=on # linux

永久设置环境变量:

再次生成 go.mod 文件:

执行完毕,发现项目下生成 go.mod 文件:

这里的模块名称是我们自定义的,不是说非得和哪个目录或者项目名对应上!

2、用户注册

2.1、需求

  • 用户向地址 /register 发送POST请求(表单携带着 username、password、phone)
  • 后端处理请求(检查手机号位数、手机号是否已经被注册、用户名是否为空)

2.2、需求实现

2.2.1、判断手机号是否存在

func isPhoneExist(db gorm.DB, phone string) bool {
  user := User{}
  db.Where("phone = ?", phone).First(user)
  if user.ID != 0 {
    return true
  }
  return false
}

2.2.2、生成随机10位的用户名

func RandomString(length int) string {
  var letters = []byte("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM")
  result := make([]byte, length)
 
  rand.Seed(time.Now().Unix())
  for i := range result {
    result[i] = letters[rand.Intn(len(letters))]
  }
  return string(result)
}

2.2.3、设置用户表结构体

       这个结构体的字段会对应用户表中的每个字段,我们会在初始化数据库的时候,使用 gorm.DB 的  AutoMigrate 方法自动帮我进行创建这个结构体对应的表。

type User struct {
  gorm.Model
  Name     string `gorm:"type:varchar(20);not null"`
  Phone    string `gorm:"type:varchar(110);not null,unique"`
  Password string `gorm:"size:255;not null"`
}

其中 gorm.Model 的源码如下:

我们通过嵌套 gorm.Model 来给我们的表增加四个字段。

2.2.4、获得数据库连接(gorm)

func InitDB() *gorm.DB {
  driverName := "mysql"
  host := "127.0.0.1"
  port := 3306
  database := "go_web"
  username := "root"
  password := "xxxxx"
  charset := "utf8mb4"
 
  args := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true", username, password, host, port, database, charset)
 
  db, err := gorm.Open(driverName, args)
  if err != nil {
    panic("failed to connect database, err : " + err.Error())
  }
  db.AutoMigrate(&User{}) // 如果表不存在则自动创建
  return db
}

2.3、完整代码

package main
 
import (
  "fmt"
  "github.com/gin-gonic/gin"
  _ "github.com/go-sql-driver/mysql"
  "github.com/jinzhu/gorm"
  "math/rand"
  "net/http"
  "time"
)
 
type User struct {
  gorm.Model
  Name     string `gorm:"type:varchar(20);not null"`
  Phone    string `gorm:"type:varchar(110);not null,unique"`
  Password string `gorm:"size:255;not null"`
}
 
func main() {
 
  db := InitDB()
  defer db.Close()
 
  engine := gin.Default()
  engine.POST("/register", func(ctx *gin.Context) {
    // 获取参数
    name := ctx.PostForm("username")
    phone := ctx.PostForm("phone")
    password := ctx.PostForm("password")
 
    // 数据验证
    if len(phone) != 11 {
      ctx.JSON(http.StatusUnprocessableEntity, gin.H{
        "code": 422,
        "msg":  "手机号必须为11位!",
      })
      return
    }
    if len(password) < 6 {
      // gin.H 等同于 map[string]any
      ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
        "code": 422,
        "msg":  "密码不能少于6位!",
      })
      return
    }
    if len(name) == 0 {
      name = RandomString(10)
    }
 
    fmt.Println(name, phone, password)
 
    // 判断手机号是否存在
    if isPhoneExist(*db, phone) {
      ctx.JSON(http.StatusUnprocessableEntity, gin.H{
        "msg": "用户已存在,不允许重复注册",
      })
      return
    }
 
    // 创建用户
    newUser := User{
      Name:     name,
      Phone:    phone,
      Password: password,
    }
    db.Create(&newUser)
 
    // 返回结果
    ctx.JSON(200, gin.H{
      "msg": "注册成功",
    })
  })
 
  panic(engine.Run()) // 默认端口 8080
}
 
func isPhoneExist(db gorm.DB, phone string) bool {
  user := User{}
  db.Where("phone = ?", phone).First(user)
  if user.ID != 0 {
    return true
  }
  return false
}
 
func RandomString(length int) string {
  var letters = []byte("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM")
  result := make([]byte, length)
 
  rand.Seed(time.Now().Unix())
  for i := range result {
    result[i] = letters[rand.Intn(len(letters))]
  }
  return string(result)
}
 
func InitDB() *gorm.DB {
  driverName := "mysql"
  host := "127.0.0.1"
  port := 3306
  database := "go_web"
  username := "root"
  password := "xxxxx"
  charset := "utf8mb4"
 
  args := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=true", username, password, host, port, database, charset)
 
  db, err := gorm.Open(driverName, args)
  if err != nil {
    panic("failed to connect database, err : " + err.Error())
  }
  db.AutoMigrate(&User{}) // 如果表不存在则自动创建
  return db
}

2.4、测试

使用规范的用户信息再次注册:


Go Web 开发 Demo【用户登录、注册、验证】(2)https://developer.aliyun.com/article/1534273

相关文章
|
3月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
333 4
|
5月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
482 0
|
3月前
|
JavaScript 前端开发 Java
【GoWails】Go做桌面应用开发?本篇文章带你上手Wails框架!一步步带你玩明白前后端双端的数据绑定!
wails是一个可以让你使用Go和Web技术编写桌面应用的项目 可以将它看作Go的快并且轻量级的Electron替代品。可以使用Go的功能,并结合现代化UI完成桌面应用程序的开发
860 4
|
3月前
|
开发框架 前端开发 Go
【GoGin】(0)基于Go的WEB开发框架,GO Gin是什么?怎么启动?本文给你答案
Gin:Go语言编写的Web框架,以更好的性能实现类似Martini框架的APInet/http、Beego:开源的高性能Go语言Web框架、Iris:最快的Go语言Web框架,完备的MVC支持。
426 1
|
7月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
419 61
|
7月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
7月前
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
7月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
3月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
263 1
|
5月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
356 1