JWT 在 Go 中的实现
安装 jwt-go
安装 jwt 在 go 中实现的开源库 jwt-go
1
| go get -u github.com/dgrijalva/jwt-go@latest
|
准备
使用 jwt-go 库生成 token,我们需要定义需求(claims),也就是说我们需要通过 jwt 传输的数据;这里的结构体根据自己的情况来定义,这里我只定义 id 和用户名;
除了自己定义的字段,还需要添加在 jwt-go 包中预定义的 jwt.StandardClaims 字段
1 2 3 4 5
| type Claims struct { ID int64 Username string jwt.StandardClaims }
|
其中 jwt.StandardClaims 中的字段有
1 2 3 4 5 6 7 8 9
| type StandardClaims struct { Audience string `json:"aud,omitempty"` ExpiresAt int64 `json:"exp,omitempty"` Id string `json:"jti,omitempty"` IssuedAt int64 `json:"iat,omitempty"` Issuer string `json:"iss,omitempty"` NotBefore int64 `json:"nbf,omitempty"` Subject string `json:"sub,omitempty"` }
|
1 2 3 4 5 6 7 8
| ## 以上字段的意思 Audience 接收jwt的一方 ExpiresAt jwt的过期时间,必填 Id id IssuedAt jwt的签发时间 Issuer jwt的签发者 NotBefore 定义在什么时间之前,该jwt都是不可用的 Subject jwt所面对的用户
|
生成 token
在 jwt-go 库中生成 token 需要用到以下 2 个方法:
- jwt.NewWithClaims
- SignedString
jwt.NewWithClaims()方法
1
| func NewWithClaims(method SigningMethod, claims Claims) *Token
|
该方法需要传入 SigningMethod 类型参数和自定义 Claims 参数;
SigningMethod 类型参数代表这 crypth.Hash 加密算法的方案,取值有 3 个,分别是
1 2 3
| jwt.SigningMethodHS256 jwt.SigningMethodHS384 jwt.SigningMethodHS512
|
参数 2 是 Claims,包含自定义类型和 StandardClaim,StandardClaim 嵌入在自定义类型中,以方便对标准声明进行编码,解析和验证。
SignedString()方法
上面的 jwt.NewWithClaims() 方法会返回一个 token 指针,通过该指针调用 SignedString 方法
SignedString 方法根据传入的空接口类型参数 key,返回完整的签名令牌。
1
| func (t *Token) SignedString(key interface{}) (string, error)
|
生成 token 实例
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
|
func GenerateToken() (string, error) { nowTime := time.Now() expireTime := nowTime.Add(300 * time.Second) issuer := "frank" claims := Claims{ ID: 10001, Username: "frank", StandardClaims: jwt.StandardClaims{ ExpiresAt: expireTime.Unix(), Issuer: issuer, }, } token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte("golang")) return token, err }
|
解析 token
使用 jwt-go 库解析 token,主要用到两个方法,分别用通过与解析传入的 token 字符串,和根据 MyCustomClaims 结构体定义的相关属性要求进行校验。
用到以下 2 个方法:
- ParseWithClaims()
- Valid()
ParseWithClaims()方法
1
| func jwt.ParseWithClaims(tokenString string, claims jwt.Claims, keyFunc jwt.Keyfunc) (*jwt.Token, error)
|
传入 token、Cliam 空对象指针以及一个函数对象;该函数对象传入 token,返回密钥数组
Valid()方法
方法用于校验鉴权的声明
实例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func ParseToken(token string) (*Claims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { return []byte("golang1"), nil }) if err != nil { return nil, err } if tokenClaims != nil { if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid { return claims, nil } } return nil, err }
|
参考文章
Golang 语言使用 jwt-go 库生成和解析 token
golang 之 JWT 实现
golang iris 的 jwt 实践,获取 jwt、携带 jwt、验证 jwt、设置过期时间、自定义错误处理函数、格式化错误返回