Gin整合Jwt-基础token操作1

快速上手

安装 jwt-go依赖:go get github.com/dgrijalva/jwt-go


原理简介

由于个人能力的原因,大家如果想查看完整的jwt验证流程,请直接访问这位大佬写的文章,极其详细与严谨:快速跳转


定义 claim 以及属性

新建文件 jwt.go,我们将在里面编写关于 token 生成、校验的基础方法

claim 即 jwt 的载荷(payload)

Name 属性为我们自定义的载荷,而 jwt.StandardClaims 则为 jwt 自带的属性(比如生命周期以及 token 开始作用的时间啥的)

type customClaim struct {
    
    
	Name string `json:"name"`
	jwt.StandardClaims
}

除此之外我们还需要两个关键参数:密钥以及生命周期

密钥作为第三个参数传递给 jwt 直接进行编码加密;
生命周期可检测 token 是否已经过期;

注意密钥的类型必须是 []byte

var (
	secret        = []byte("hellojwt")  // 密钥
	expTime int64 = 30                  // 生命周期,单位为秒
)

生成 token

由于我们定义的 claim 仅有一个自定义属性,则生成 token 的形参我们也仅需传递该值即可

这里定义了两个 jwt 字段,ExpiresAt(生命周期),以及 Issuer(签发者);
字段都不是必须的,但是为了完整性最好添加;

func GenerateToken(name string) (string, error) {
    
    

    // 实例化claim
	claim := customClaim{
    
    
        // 定义自定义属性
		Name: name,
        // 定义jwt自带的属性
		StandardClaims: jwt.StandardClaims{
    
    
			ExpiresAt: int64(time.Now().Unix() + expTime), // 生命周期
			Issuer:    "zhiller",                          // 签发者
		},
	}

    // 通过claim创建原始token
    // 参数一:加密编码;参数二:使用的claim
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)

    // 使用指定的密钥对原始token进行签名,获得加密后的token
	return token.SignedString(secret)
}

解析 token

没什么好说的,直接拿到 token,使用指定的 claim 结构配合密钥进行解密即可

func ParseToken(token string) (*jwt.Token, *customClaim, error) {
    
    
	claim := &customClaim{
    
    }

    // 解析token的固定格式,第三个参数golang会自动生成
	t, err := jwt.ParseWithClaims(token, claim, func(token *jwt.Token) (interface{
    
    }, error) {
    
    
		return secret, nil
	})

	return t, claim, err
}

校验 token

步骤较多,请直接看注释

这里使用到了上面我们写的 ParseToken 作为解析 token

func ValidateToken(token string) bool {
    
    

    // ParseToken解析token
	_, _, err := ParseToken(token)

    // 如果解析出了问题
	if err != nil {
    
    
        // 获得错误类型
		if tp, ok := err.(*jwt.ValidationError); ok {
    
    
            // 将获取的类型与指定错误类型进行位与,非0表示确为该类型错误
            // jwt.ValidationErrorExpired表示超出生命周期错误
			if tp.Errors&jwt.ValidationErrorExpired != 0 {
    
    
                // 遇到错误了当然返回校验失败了呀
				return false
			}
		}
	}

    // 如果解析无问题,表示校验成功
	return true
}

完整代码

package middleware

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"time"
)

type customClaim struct {
    
    
	Name string `json:"name"`
	jwt.StandardClaims
}

var (
	secret        = []byte("hellojwt")
	expTime int64 = 30
)

func GenerateToken(name string) (string, error) {
    
    
	claim := customClaim{
    
    
		Name: name,
		StandardClaims: jwt.StandardClaims{
    
    
			ExpiresAt: int64(time.Now().Unix() + expTime),
			Issuer:    "zhiller",
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
	return token.SignedString(secret)
}

func ParseToken(token string) (*jwt.Token, *customClaim, error) {
    
    
	claim := &customClaim{
    
    }
	t, err := jwt.ParseWithClaims(token, claim, func(token *jwt.Token) (interface{
    
    }, error) {
    
    
		return secret, nil
	})
	fmt.Printf("parse the token: %v\n", t)
	return t, claim, err
}

func ValidateToken(token string) bool {
    
    
	_, _, err := ParseToken(token)
	if err != nil {
    
    
		if tp, ok := err.(*jwt.ValidationError); ok {
    
    
			if tp.Errors&jwt.ValidationErrorExpired != 0 {
    
    
				return false
			}
		}
	}

	return true
}

猜你喜欢

转载自blog.csdn.net/delete_you/article/details/128751423