使用gin -gorm-jwt-中间件拦截的一个小项目

用gin +gorm+jwt实现登录注册的小项目

这个项目主要使用了gin+gorm+jwt实现的登录注册功能,另外还通过定义中间件的方式,实现了对请求进行权限校验后放行的功能。非常适合练手。如果有新的想法也欢迎来我评论区分享一下。

目录:

文章目录

一、项目结构:

二、各个目录的介绍

1.config目录

config/app.yml

yml 复制代码
mysql:
  dns: root:123456@tcp(127.0.0.1:3306)/logintest?charset=utf8mb4&parseTime=True

2.helper目录

helper/helper.go

go 复制代码
package helper
import(
	"fmt"
	"github.com/dgrijalva/jwt-go"
	uuid "github.com/satori/go.uuid"
	"time"
)
func GetUUID() string {
	return uuid.NewV4().String()
}
//使用jwt
type UserClaims struct{
	Identity string `json:"identity"`
	Name string `json:"name"`
	IsAdmin  int    `json:"is_admin"`
	jwt.StandardClaims
}

//定义密钥
var myKey =[]byte("lcc7758258")

//生成token
func GenerateToken(identity ,name string,isAdmin int)(string,error){
	//设置过期时间为2分钟
	exprirationTime :=time.Now().Add(2 * time.Minute)
	UserClaim :=&UserClaims{
		Identity: identity,
		Name: name,
		IsAdmin: isAdmin,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: exprirationTime.Unix(),
		},
	}
	//生成一个token
	token :=jwt.NewWithClaims(jwt.SigningMethodHS256,UserClaim)
	//对token 进行加盐操作
	tokenString,err :=token.SignedString(myKey)
	fmt.Println(tokenString)
	if err !=nil{
		return "token生成失败,这里", err
	}
	return tokenString,nil //将生成的token返回出去
}

//解析token
func TestAnalyseToken(tokenString string)(*UserClaims,error){
	UserClaim :=new(UserClaims)
	claims,err :=jwt.ParseWithClaims(tokenString,UserClaim,func(token *jwt.Token) (interface{},error){
		return myKey,nil
	})
	if err !=nil {
		return nil,err
	}
	if !claims.Valid{
		return nil,fmt.Errorf("analyse Token Error: #{err}")
	}
	return UserClaim,nil
}

3.middlewares目录

middlewares/auth_admin.go

go 复制代码
package middlewares

import (
	"github.com/gin-gonic/gin"
	"loginTest/helper"
	"net/http"
)

func AuthAdminCheck() gin.HandlerFunc {
	return func(c *gin.Context) {
		auth :=c.GetHeader("Authorization")
		//解析token
		userClaim,err :=helper.TestAnalyseToken(auth);
		if err !=nil{
			c.Abort()
			c.JSON(http.StatusOK,gin.H{
				"code":http.StatusUnauthorized,
				"message":"token验证不成功,也就是解析错误啦",
			})
			return
		}
		//不是管理员
		if userClaim ==nil || userClaim.IsAdmin !=1{
			c.Abort()
			c.JSON(http.StatusOK,gin.H{
				"code":http.StatusUnauthorized,
				"message":"不是管理员,也没有用啦",
			})

			return
		}

		c.Next()

	}
}

4.models目录

models/init.go

go 复制代码
package models

import (
	"fmt"
	"github.com/spf13/viper"
	"gorm.io/gorm"
	"gorm.io/driver/mysql"
	"gorm.io/gorm/logger"
	"log"
)

var DB= Init()


func Init() *gorm.DB{
     viper.SetConfigName("app")
     viper.AddConfigPath("config")
     viper.ReadInConfig()
     err :=viper.ReadInConfig()
     if err !=nil{
     	fmt.Println(err)
	 }
	 fmt.Println("config文件加载成功")
     db,err :=gorm.Open(mysql.Open(viper.GetString("mysql.dns")),&gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	 })
     if err !=nil{
     	log.Println("gorm Init Error",err)
	 }
	 return db
}

models/UserBasic.go

go 复制代码
package models

import (
	"fmt"
	"gorm.io/gorm"
)

type UserBasic struct{
	gorm.Model
	Identity 		string `gorm:"column:identity;type:varchar(36);" json:"identity"`
	Name            string `gorm:"column:name;type:varchar(100);"json:"name"`
	Password        string `gorm:"column:password;type:varchar(32);" json:"password"`
	IsAdmin			int		`gorm:"column:is_admin;type:tinyint(1);" json:"is_admin"`
}
//数据库表名
func (table *UserBasic) TableName() string {
	return "user_basic"
}

func GetUserList()[]*UserBasic{
	data :=make([]*UserBasic,6)
	DB.Find(&data)
	for _,v :=range data{
		fmt.Println(v)
	}
	return data

}

5.router

router/app.go

go 复制代码
package router
import(
	"github.com/gin-gonic/gin"
	"loginTest/middlewares"
	"loginTest/service"
)
func Router() *gin.Engine{
	r :=gin.Default()


	r.GET("/ping",service.Ping)
	r.POST("/registers",service.Register)
	r.POST("/logins",service.Login)
	r.GET("/getuserlist",service.GetUserList)

	authAdmin:=r.Group("/admin",middlewares.AuthAdminCheck())

	authAdmin.GET("/loginok",service.LoginOk)

	//加上中间件进行拦截操作

	return r
}

6.Service目录

service/ping.go

go 复制代码
package service

import "github.com/gin-gonic/gin"

func Ping(c *gin.Context){
	c.JSON(200,gin.H{
		"message":"pong",
	})
}

service/user.go

go 复制代码
package service

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"loginTest/helper"
	"loginTest/models"
	"net/http"
)
//注册操作
func Register(c *gin.Context){
	name :=c.PostForm("name")
	password :=c.PostForm("password")

	fmt.Println("name的值是",name)
	if name ==" " || password ==" "{
		c.JSON(http.StatusOK,gin.H{
			"code":-1,
			"msg":"参数不正确,密码或者名字为空",
		})
		return
	}
	//数据的插入
	Identity := helper.GetUUID()
	data :=models.UserBasic{
		Identity: helper.GetUUID(),
		Name : name,
		Password: password,
	}
	fmt.Println("data.Name的值是",data.Name)
	err :=models.DB.Create(&data).Error
	if err !=nil{
		c.JSON(http.StatusOK,gin.H{
			"code": -1,
			"msg":"Create User Error" + err.Error(),
		})
		return
	}
	//生成token
	token ,err :=helper.GenerateToken(Identity,name,data.IsAdmin)

	if err !=nil{
		c.JSON(http.StatusOK,gin.H{
			"code":-1,
			"msg":"Generate Token是无效的 Error"+err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code":200,
		"data":map[string]interface{}{
			"token":token,
		},
	})
}
//登录操作
func Login(c *gin.Context){
	name :=c.PostForm("name")
	password :=c.PostForm("password")
	if name=="" || password ==""{
		c.JSON(http.StatusOK,gin.H{
			"code":-1,
			"msg":"必填信息为空",
		})
	}
	data :=new(models.UserBasic)
	err :=models.DB.Where("name=? And password=?",name,password).First(&data).Error
	if err !=nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusOK, gin.H{
				"code": -1,
				"msg":  "用户名或密码错误",
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code": -1,
			"msg":  "Get UserBasic Error:" + err.Error(),
		})
		return
	}
	token,err :=helper.GenerateToken(data.Identity,data.Name,data.IsAdmin)
	if err !=nil{
		c.JSON(http.StatusOK,gin.H{
			"code":-1,
			"msg":"GenerateToken Error:"+ err.Error(),
		})
	}
	c.JSON(http.StatusOK,gin.H{
		"code":200,
		"data":map[string]interface{}{
			"token":token,
		},
	})
}
func GetUserList(c *gin.Context){
	data :=make([]*models.UserBasic,6)
	data =models.GetUserList()
	c.JSON(http.StatusOK,gin.H{
		"code":0,
		"mgs":"查询成功",
		"data":data,
	})
}

func LoginOk(c *gin.Context){
	c.JSON(http.StatusOK,gin.H{
		"code":1,
		"msg" :"已经通过验证登录成功。",
	})
}

7.main.go

go 复制代码
package main

import (
	"loginTest/models"
	"loginTest/router"
)

func main(){
	//进行数据迁移
	models.DB.AutoMigrate(&models.UserBasic{})
	r:=router.Router()
	r.Run(":9091")
}

三、postman测试:

1.尝试注册:

2.尝试登录:

3.尝试拦截

相关推荐
小柯J桑_1 小时前
C++:探索AVL树旋转的奥秘
开发语言·c++·avl树
数学人学c语言1 小时前
从熟练Python到入门学习C++(record 6)
c++·python·学习
skaiuijing3 小时前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
Simulink_4 小时前
ROS学习笔记15——Xacro
linux·笔记·学习·机器人·ros
雯0609~4 小时前
c#:winform调用bartender实现打印(学习整理笔记)
开发语言·c#
2301_775281195 小时前
当日本人说「お疲れ様」时,该怎么回?柯桥日语培训零基础学习
学习
E___V___E5 小时前
CSAPP学习
学习
胜天半子_王二_王半仙5 小时前
c++源码阅读__smart_ptr__正文阅读
开发语言·c++·开源
沐泽Mu5 小时前
嵌入式学习-C嘎嘎-Day08
开发语言·c++·算法
Non importa5 小时前
汉诺塔(hanio)--C语言函数递归
c语言·开发语言·算法·学习方法