Gin JWT实现代码

对部分代码的接口做了二次实现,满足目前的需求

以下为中间件中的代码:

package jwt

import (
	"errors"
	"fmt"
	"gitee.com/xxx/xxx/model"
	"gitee.com/xxx/xxx/tools"
	"github.com/appleboy/gin-jwt/v2"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"net/http"
	"time"
)

var Auth *jwt.GinJWTMiddleware
var identityKey = "id"
var realm string
var jwtSecretKey string

type User struct {
	Id       uint64 `json:"id"`
	Username string `json:"username"`
}

func init() {

}

func JNew() {
	tools.DebugPrint("=========== JWT 初始化参数", viper.GetString("jwtKey"),
		viper.GetString("app_name"), "=================")

	realm = viper.GetString("app_name")
	jwtSecretKey = viper.GetString("jwtKey")
	
	Auth, _ = jwt.New(&jwt.GinJWTMiddleware{
		Realm:           realm,
		Key:             []byte(jwtSecretKey),
		Timeout:         time.Hour * 30 * 24,
		MaxRefresh:      time.Second * 30,
		IdentityKey:     identityKey,
		PayloadFunc:     payloadFunc,
		IdentityHandler: identityHandler,
		Authenticator:   authenticator,
		Authorizator:    authorizator,
		Unauthorized:    unauthorized,
		TokenLookup:     "header:Authorization, query:token, cookie:jwt",
		TokenHeadName:   "Bearer",
		TimeFunc:        time.Now,
		RefreshResponse: refreshResponse,
		LoginResponse:   loginResponse, // 登录返回jwt-token
	})
}

// 登录返回jwt-token
func loginResponse(c *gin.Context, code int, token string, expire time.Time) {
	tools.DebugPrint("LoginResponse")
	data := make(map[string]string)
	data["token"] = token
	data["expire"] = expire.Format(time.RFC3339)
	if code == http.StatusOK {
		tools.Success(c, data)
		return
	}
	tools.Fail(c, "fail", data)
}

// 认证
func authenticator(c *gin.Context) (interface{}, error) {
	tools.DebugPrint("Authenticator")
	var user model.LoginModel
	if err := c.ShouldBindJSON(&user); err != nil {
		return nil, errors.New("params_lost")
	}

	userName := user.Username
	password := user.Password

	auth := model.UserDB{}
	userinfo := auth.GetUserInfoByUserName(userName)
	if userinfo.Id == 0 {
		return nil, errors.New("user_not_exist")
	}

	// 用户存在校验用户密码
	check := tools.PasswordCheck(password, userinfo.Password)
	if !check {
		return nil, errors.New("password_error")
	}

	return &User{
		Id:       userinfo.Id,
		Username: userinfo.Username,
	}, nil
}

// 授权者
func authorizator(data interface{}, c *gin.Context) bool {
	tools.DebugPrint("Authorizator")
	return true
}

// 不合法
func unauthorized(c *gin.Context, code int, message string) {
	tools.DebugPrint("Unauthorized")
	tools.Fail(c, "ERROR_AUTH_CHECK_TOKEN_FAIL", "")
	fmt.Println(code, message)
}

// payloadFunc
func payloadFunc(data interface{}) jwt.MapClaims {
	tools.DebugPrint("PayloadFunc")
	if v, ok := data.(*User); ok {
		return jwt.MapClaims{
			identityKey: v.Id,
			"username":  v.Username,
		}
	}
	return jwt.MapClaims{}
}

// 令牌信息
func identityHandler(c *gin.Context) interface{} {
	tools.DebugPrint("IdentityHandler")
	claims := jwt.ExtractClaims(c)

	return &User{
		Username: claims["username"].(string),
		Id:       uint64(claims["id"].(float64)),
	}
}

// 刷新返回函数
func refreshResponse(c *gin.Context, code int, token string, expire time.Time) {
	tools.DebugPrint("refreshResponse")
	oldToken := c.GetHeader("Authorization")[7:]

	data := make(map[string]string)
	data["expire"] = expire.Format(time.RFC3339)
	data["old_token"] = oldToken
	data["token"] = token

	if code == http.StatusOK {
		tools.Success(c, data)
		return
	}
	tools.Fail(c, "fail", data)
}

在main方法中通过jwt.JNew()初始化JWT。

使用

authRouter.POST("/login", jwt.Auth.LoginHandler)

userRouter := router.Group("/user", jwt.Auth.MiddlewareFunc())

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论审核已启用。您的评论可能需要一段时间后才能被显示。