-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.go
116 lines (106 loc) · 3.39 KB
/
jwt.go
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package jwt
import (
"errors"
"github.com/dgrijalva/jwt-go"
)
// JwtSign 结构体
type JwtSign struct {
SigningKey []byte
}
// 一些常量
var (
TokenExpired = errors.New("token is expired")
TokenNotValidYet = errors.New("token not active yet")
TokenMalformed = errors.New("that's not even a token")
TokenInvalid = errors.New("couldn't handle this token")
)
// CustomClaims 用于构成payload
type CustomClaims struct {
UserID string `json:"user_id"`
jwt.StandardClaims
}
// 新建一个JwtSign实例
func NewJwtSign(jwtSecret string) *JwtSign {
return &JwtSign{
[]byte(jwtSecret),
}
}
// CreateToken 生成一个token
func (j *JwtSign) CreateToken(claims CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(j.SigningKey)
}
// ParseToken 解析一个token
func (j *JwtSign) ParseToken(tokenString string) (*CustomClaims, error) {
// 因为我们只使用一个私钥来签署令牌,所以我们也只使用它的公共计数器部分来验证
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, TokenMalformed
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
return nil, TokenExpired
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, TokenNotValidYet
} else {
return nil, TokenInvalid
}
} else {
return nil, TokenInvalid
}
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
}
// RefreshToken 更新一个token
// func (j *JwtSign) RefreshToken(tokenString string) (string, error) {
// jwtDuration, _ := time.ParseDuration(conf.JwtDuration)
// jwt.TimeFunc = func() time.Time {
// return time.Unix(0, 0)
// }
// token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
// return j.SigningKey, nil
// })
// if err != nil {
// return "", err
// }
// if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
// jwt.TimeFunc = time.Now
// claims.StandardClaims.ExpiresAt = time.Now().Add(jwtDuration).Unix()
// return j.CreateToken(*claims)
// }
// return "", TokenInvalid
// }
// GetClaimsFromExpiredToken 从一个过期的token中获取claims
func (j *JwtSign) GetClaimsFromExpiredToken(tokenString string) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
return j.SigningKey, nil
})
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, TokenMalformed
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, TokenNotValidYet
// 如果token是过期了,仍然返回claims,为了从过期的token中获取userID
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
if claims, ok := token.Claims.(*CustomClaims); ok { // 这里删掉了token.valid
return claims, nil
}
return nil, TokenExpired
} else {
return nil, TokenInvalid
}
} else {
return nil, TokenInvalid
}
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
}