go-jwt

工具代码

package tool

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

/**
Go 实现 JWT 的底层原理涉及以下主要步骤:
创建 JWT:
构建包含标准声明(jwt.StandardClaims)和自定义声明的声明结构体。
使用 jwt.NewWithClaims 方法使用指定的签名方法(如 HS256、ES256 等)创建一个 JWT 实例。
使用 SignedString 方法将 JWT 实例和密钥进行签名生成最终的 JWT。
验证和解析 JWT:
使用 jwt.ParseWithClaims 方法解析 JWT,并传入声明结构体的实例作为第二个参数。
为有效的签名密钥提供 jwt.Keyfunc 方法,用于验证签名。
在 jwt.ParseWithClaims 方法中指定解析选项(如 SkipClaimsValidation、IgnoreExpiration 等)。
解析完 JWT 后,可以从声明结构体中获取 JWT 中的信息。
底层实现原理包括了 JWT 的编码、解码和签名验证。编码涉及将声明结构体中的声明转换为字符串,并进行 Base64 编码。签名验证涉及将 JWT 中的签名部分与预期的签名进行比对,以确保 JWT 的完整性。
*/

// 指定加密密钥
var jwtSecret = []byte("43286a86706620e38c333cdd4c496355")
var ExpirationTime time.Duration = time.Second * 20 //二十秒

type Claims struct {
	jwt.StandardClaims                   // 继承 jwt.StandardClaims,包含了 JWT 标准声明字段信息,如过期时间、签发者等
	AdditionalData     map[string]string // 额外的数据字段,用于存储自定义的键值对属性
}

var attribute = map[string]string{} //存储多少个属性

func init() {
	//可以使用for循环存储多个属性数值
	attribute["userName"] = "adasd"
	attribute["id"] = "12"
	attribute["password"] = "asdfg"
}

// 根据用户的用户名和密码产生token
func GenerateToken() (string, error) {
	//设置token有效时间
	nowTime := time.Now()
	expireTime := nowTime.Add(ExpirationTime)
	claims := Claims{
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(), // 过期时间
			Issuer:    "Gst",             // 指定token发行人
		},
		AdditionalData: attribute,
	}
	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := tokenClaims.SignedString(jwtSecret) //该方法内部生成签名字符串,再用于获取完整、已签名的token
	return token, err
}

// 根据传入的token值获取到Claims对象信息,(进而获取其中的用户名和密码)
func ParseToken(token string) (*Claims, error, map[string]string) {
	claims := &Claims{}
	//用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token
	tokenClaims, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
		return jwtSecret, nil
	})
	message := map[string]string{}
	for key, value := range claims.AdditionalData { //todo 获取额外属性
		message[key] = value
	}
	if tokenClaims != nil {
		// 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims
		// 要传入指针,项目中结构体都是用指针传递,节省空间。
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil, message
		}
	}
	return nil, err, nil
}

测试代码

package test

import (
	"beego_test/tool"
	"fmt"
	"testing"
)

func Test_jwt(t *testing.T) {
	token, err := tool.GenerateToken()
	if err != nil {
		fmt.Println("加密失败")
		return
	}
	fmt.Println("加密字符串为", token)
	_, _, message := tool.ParseToken(token)
	for key, value := range message {
		fmt.Println("key value", key, value)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超维Ai编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值