您现在的位置是:首页 >技术交流 >Go语言项目使用gin框架和gorm框架实现后端的注册和登录功能网站首页技术交流

Go语言项目使用gin框架和gorm框架实现后端的注册和登录功能

Dragon_0010 2023-06-09 16:00:03
简介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.结果展示

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。