前言

jwt是一种用于用户认证的数字签名解决方案,形式为header.payload.signature,数据用base64进行编码,signature是把前面的数据与密钥结合进行计算hash的结果,下面是一种hash算法计算signature的方式

1
2
3
4
5
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)

payload可以添加数据,在校验时会据此有不同的处理,比如可以加入时间戳限定有效期,加入用户名等标识进行用户认证

安装

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

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main

import (
"errors"
"fmt"
"time"

"github.com/golang-jwt/jwt/v5"
)

func GenerateToken(name string) (string, error) {
claims := jwt.RegisteredClaims{
// 设置过期时间,这里设置一个小时后过期
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
// 颁发时间
IssuedAt: jwt.NewNumericDate(time.Now()),
//主题: 标识 Token 的主体,通常是用户 ID 或用户名
Subject: name,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(signKey)
}

func ParseToken(tokenStr string) (jwt.RegisteredClaims, error) {
var claims jwt.RegisteredClaims
//第一个值是token
//第二个值是我们之后需要把解析的数据存放的指针
//第三个是回调函数,用于返回验证的秘钥,因为秘钥可以是与claims的内容相关的
token, err := jwt.ParseWithClaims(tokenStr, &claims, func(token *jwt.Token) (interface{}, error) {
return signKey, nil
})
if err != nil && !token.Valid {
err = errors.New("invalid Token")
}
return claims, err
}

var signKey = []byte("AllYourBase")

func main() {

token, err := GenerateToken("admin")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(token)
parseToken, err := ParseToken(token)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%+v", parseToken)

}

可以自定义Claims,只要嵌入jwt.RegisteredClaims,就实现了这个结构体的接口,可以添加更多的属性到payload里