您现在的位置是:首页 >技术交流 >Go语言项目使用gin框架和gorm框架实现后端的注册和登录功能网站首页技术交流
Go语言项目使用gin框架和gorm框架实现后端的注册和登录功能
简介Go语言项目使用gin框架和gorm框架实现后端的注册和登录功能
1.环境准备
1.下载git并配置环境变量
下载地址:Git
一路都是next
用户变量的path里面添加Gitin的路径
git安装完验证
2.打开GoLand导入gin框架和gorm框架的依赖
1.初始化项目
2.导入gin的依赖
gin官网:Quickstart | Gin Web Framework
打开goland的终端,输入以下代码
go get -u github.com/gin-gonic/gin
依赖下载完毕
3.导入gorm框架的依赖
gorm框架官网:GORM Guides | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
复制以下代码到goland的终端
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
下载完毕
复制以下代码到goland的终端
go get -u gorm.io/driver/mysql
下载完毕
数据库版本:8.0.26
2.代码的完成
1.项目的结构
新建包:
common包里面的database.go是数据库的连接信息
controller包里面的UserCtroller.go是用户的控制层业务逻辑代码
model包里面的是实体类信息
util包里面是配置文件,一些封装好的函数可以放在里面
go.mod里面是依赖的路径
main.go是启动项目的主方法
routes.go是请求的路径
2.项目开始
各部分代码
database.go
package common
import (
"fmt"
"ginEssential/model"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
// 开启连接池
func InitDB() *gorm.DB {
host := "localhost"
port := "3306"
database := "ginessential"
username := "root"
password := "1234"
charset := "utf8"
args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
username,
password,
host,
port,
database,
charset)
db, err := gorm.Open(mysql.Open(args), &gorm.Config{})
if err != nil {
panic("failed to connect database,err: " + err.Error())
}
//自动创建数据表
db.AutoMigrate(&model.User{})
DB = db
return db
}
func GetDB() *gorm.DB {
return DB
}
UserCtroller.go
package controller
import (
"ginEssential/common"
"ginEssential/model"
"ginEssential/util"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
"log"
"net/http"
)
func Register(ctx *gin.Context) {
DB := common.GetDB()
//获取参数
name := ctx.PostForm("name") //注意字符串要用双引号
telephone := ctx.PostForm("telephone")
password := ctx.PostForm("password")
//数据验证
if len(telephone) != 11 {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位"})
return
}
if len(password) < 6 {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "密码不能少于6位"})
return
}
//如果没有传name(名称),就给他一个10位的随机字符串
if len(name) == 0 {
name = util.RandomString(10)
}
log.Println(name, telephone, password)
//判断手机号是否存在
if isTelephoneExist(DB, telephone) {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "用户已经存在"})
}
//如果用户不存在,则创建用户
//对密码进行加密
hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 500, "msg": "加密错误"})
return
}
newUser := model.User{
Name: name,
Telephone: telephone,
Password: string(hasedPassword), //将加密后的密码保存起来
}
DB.Create(&newUser)
//返回结果
ctx.JSON(200, gin.H{
"message": "注册成功",
})
}
// 登录功能
func Login(ctx *gin.Context) {
DB := common.GetDB()
//获取参数
telephone := ctx.PostForm("telephone")
password := ctx.PostForm("password")
//数据验证
if len(telephone) != 11 {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位"})
return
}
if len(password) < 6 {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "密码不能少于6位"})
return
}
//判断手机号是否存在
var user model.User
DB.Where("telephone = ?", telephone).First(&user)
if user.ID == 0 {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "用户不存在"})
return
}
//判断密码是否正确
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "密码错误"})
return
}
//发送token
token := "11"
//返回结果
ctx.JSON(200, gin.H{
"code": 200,
"data": gin.H{"token": token},
"msg": "登录成功",
})
}
// 判断手机号是否存在
func isTelephoneExist(db *gorm.DB, telephone string) bool {
var user model.User
db.Where("telephone = ?", telephone).First(&user)
if user.ID != 0 {
return true
}
return false
}
user.go
package model
import "gorm.io/gorm"
// 定义一个Model
type User struct {
gorm.Model
Name string `gorm:"type:varchar(20);not null"`
Telephone string `gorm:"varchar(11);not null;unique"`
Password string `gorm:"size:255;not null"`
}
util.go
package util
import (
"math/rand"
"time"
)
// 随机生成字符串的函数
func RandomString(n int) string {
var letters = []byte("asdfghjklzxcvbnmqwertyuiopASDFGHJKLZXCVBNMQWERTYUIOP")
result := make([]byte, n)
rand.Seed(time.Now().Unix())
for i := range result {
result[i] = letters[rand.Intn(len(letters))]
}
return string(result)
}
main.go
// 创建main。go的第一步就是将package的名称改成main,不然运行的时候,会报系统兼容的错误
package main
import (
"ginEssential/common"
"github.com/gin-gonic/gin"
)
func main() {
db := common.InitDB()
//获取底层数据库连接
sqlDB, err := db.DB()
if err != nil {
panic("failed to connect database,err: " + err.Error())
}
defer sqlDB.Close()
r := gin.Default()
r = collectRoute(r)
panic(r.Run()) // listen and serve on 0.0.0.0:8080
}
routes.go
package main
import (
"ginEssential/controller"
"github.com/gin-gonic/gin"
)
func collectRoute(r *gin.Engine) *gin.Engine {
r.POST("/api/auth/resgister", controller.Register)
r.POST("/api/auth/login", controller.Login)
return r
}
3.结果展示
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。