用gin +gorm+jwt实现登录注册的小项目
这个项目主要使用了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")
}