【笔记】Go语言通过JWT生成Token

前言

Go语言通过JWT生成Token

github.com/dgrijalva/jwt-go

下载依赖

1
go get github.com/dgrijalva/jwt-go

定义一个结构体

  • 定义一个结构体,继承jwt.StandardClaims结构体
1
2
3
4
type 结构体名 struct {
jwt.StandardClaims
自定义属性 数据类型
}

生成Token字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 定义密钥
var secret = []byte{'0'}

// 当前时间
var now = time.Now()
// 生效时间
var notBefore = now.Unix() - 30
// 过期时间
var expiresAt = now.Unix() - 30 + int64(time.Hour*24*3)

// 生成Token对象
var token = jwt.NewWithClaims(jwt.SigningMethodHS256, 结构体名{
StandardClaims: jwt.StandardClaims{
NotBefore: notBefore,
ExpiresAt: expiresAt,
},
自定义属性: 属性值,
})

// 加密令牌,得到Token字符串
tokenStr, _ := token.SignedString(secret)

直接获取Token字符串的Payload数据

1
2
3
4
token, _ := jwt.ParseWithClaims(令牌字符串, &结构体名{}, func(token *jwt.Token) (interface{}, error) {
return nil, nil
})
var notBefore = token.Claims.(*结构体名).NotBefore

校验Token字符串

1
2
3
4
5
6
7
8
if res, err := jwt.ParseWithClaims(令牌字符串, &结构体名{}, func(token *jwt.Token) (interface{}, error) {
return secret, nil
}); err != nil {
// 校验失败
} else {
// 校验成功,获取Payload数据
payload = res.Claims.(*结构体名)
}

github.com/golang-jwt/jwt/v5

下载依赖

1
go get github.com/golang-jwt/jwt/v5

定义一个结构体

  • 定义一个结构体,继承jwt.RegisteredClaims结构体
1
2
3
4
type 结构体名 struct {
jwt.RegisteredClaims
自定义属性 数据类型
}

生成Token字符串

  • StandardClaims中属性的时间值不能是时间戳,必须是*NumericDate时间类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 定义密钥
var secret = []byte{'0'}

// 当前时间
var now = time.Now()
// 生效时间
var notBefore = now.Add(time.Second - 30*(-1))
// 过期时间
var expiresAt = now.Add(time.Second - 30*(-1)).Add(time.Hour * 24 * 3)

// 生成Token对象
var token = jwt.NewWithClaims(jwt.SigningMethodHS256, 结构体名{
StandardClaims: jwt.StandardClaims{
NotBefore: jwt.NewNumericDate(notBefore),
ExpiresAt: jwt.NewNumericDate(expiresAt),
},
自定义属性: 属性值,
})

// 加密令牌,得到Token字符串
tokenStr, _ := token.SignedString(secret)

直接获取Token字符串的Payload数据

1
2
3
4
token, _ := jwt.ParseWithClaims(令牌字符串, &结构体名{}, func(token *jwt.Token) (interface{}, error) {
return nil, nil
})
var notBefore = token.Claims.(*结构体名).NotBefore

校验Token字符串

1
2
3
4
5
6
7
8
if res, err := jwt.ParseWithClaims(令牌字符串, &结构体名{}, func(token *jwt.Token) (interface{}, error) {
return secret, nil
}); err != nil {
// 校验失败
} else {
// 校验成功,获取Payload数据
payload = res.Claims.(*结构体名)
}

踩坑

  • 生成令牌或解析令牌时报错:token signature is invalid: key is of invalid type

原因一

  • 生成令牌或解析令牌时应当使用[]byte类型的key,而不是string类型或其他类型

解决问题

  • 生成令牌或解析令牌时应当使用[]byte类型的key

原因二

  • 加密方式应当是jwt.SigningMethodHS256而不是jwt.SigningMethodES256

完成

参考文献

博客园——奔跑的路上
jwt-go 官方文档
知乎——simpleapples
稀土掘金——水纹
哔哩哔哩——go圈里最会写js的奇淼
博客园——zichliang