1. 安装 jwt 

    1. go get -u github.com/appleboy/gin-jwt/v2
  2. 具体代码(新建 middleware 文件夹)

    1. package middleware
      
      import (
      	"crud-go/global"
      	"crud-go/models"
      	"fmt"
      	"time"
      
      	jwt "github.com/appleboy/gin-jwt/v2"
      	"github.com/gin-gonic/gin"
      )
      
      var IdentityKey = "userId"
      
      // 返回 JWT 中间件
      func NewJWTMiddleware() (*jwt.GinJWTMiddleware, error) {
      	return jwt.New(&jwt.GinJWTMiddleware{
      		Realm:       "example zone",
      		Key:         []byte("secret key"), // 签名密钥
      		Timeout:     time.Minute,
      		MaxRefresh:  time.Hour,
      		IdentityKey: IdentityKey,
      
      		// 登录验证:只用 name
      		Authenticator: func(c *gin.Context) (interface{}, error) {
                  // 我这里只是校验 接口name,实际业务的话,用户名和密码都要验证的,这里仅仅做演示即可
      			var loginVals struct {
      				Name string `json:"name"` // 前端传 name
      			}
      
      			if err := c.ShouldBindJSON(&loginVals); err != nil {
      				return nil, jwt.ErrMissingLoginValues
      			}
      
      			var user models.User
      			err := global.MysqlDB.Where("name = ?", loginVals.Name).First(&user).Error
      			if err != nil {
      				return nil, jwt.ErrFailedAuthentication
      			}
      
      			// 返回数据库查询到的用户对象
      			return &user, nil
      		},
      
      		// 写入 Token
      		PayloadFunc: func(data interface{}) jwt.MapClaims {
      			if user, ok := data.(*models.User); ok {
      				fmt.Println("user", user.ID)
      				return jwt.MapClaims{
      					IdentityKey: user.ID,   // Token 存储用户 ID
      					"username":  user.Name, // Token 存储用户名
      				}
      			}
      			return jwt.MapClaims{}
      		},
      
      		// 权限验证
      		Authorizator: func(data interface{}, c *gin.Context) bool {
                  // data 是当前用户的id,其实就是  IdentityKey 的值,这里一般做 用户角色权限验证
      			return data != nil
      		},
      
      		// 自定义 Unauthorized
      		Unauthorized: func(c *gin.Context, code int, message string) {
                  // 自定义响应
      			if code == 403 {
      				c.JSON(code, gin.H{
      					"code":  403,
      					"error": "无权限访问",
      				})
      			} else {
      				c.JSON(code, gin.H{
      					"code":  code,
      					"error": message,
      				})
      			}
      		},
      
      		// 解析 Token
      		IdentityHandler: func(c *gin.Context) interface{} {
      			claims := jwt.ExtractClaims(c)
      			return claims[IdentityKey]
      		},
      
      		TokenLookup:   "header: Authorization",
      		TokenHeadName: "Bearer",
      		TimeFunc:      time.Now,
      	})
      }
      
  3. 路由配置

    1. package routers
      
      import (
      	"crud-go/controller"
      	"crud-go/middleware"
      	"log"
      
      	"github.com/gin-gonic/gin"
      )
      
      // 自动执行,根据go 的一个机制,在编译时自动调用init函数,执行一些初始化操作
      func InitRouter() *gin.Engine {
      	r := gin.Default()
      
      	// 初始化 JWT,一开始初始的路由,顺便初始token 的生成
      	authMiddleware, err := middleware.NewJWTMiddleware()
      
      	if err != nil {
      		log.Fatal("JWT Error:", err)
      	}
      
      	// 登录接口(不需要鉴权)
      	r.POST("/login", authMiddleware.LoginHandler)
      
      	api := r.Group("/api")
          // 需要token 鉴权的接口
      	api.Use(authMiddleware.MiddlewareFunc())
      	{
      		// 创建一个用户
      		api.POST("/add/user", controller.Adduser)
      		api.DELETE("/delete/user/:id", controller.DeleteUser)
      		api.PUT("/update/user", controller.UpdateUser)
      		api.GET("/get/user/:id", controller.GetUserById)
      		api.GET("/get/user", controller.GetAllUser)
      	}
      
      	return r
      }
      
  4. 项目目录

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐