-
Notifications
You must be signed in to change notification settings - Fork 0
/
qjwt.go
130 lines (116 loc) · 2.87 KB
/
qjwt.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package qjwt
import (
"context"
"errors"
"github.com/dgrijalva/jwt-go"
"github.com/qsock/qf/qlog"
"time"
)
var (
ErrInvalidConf = errors.New("conf is not valid")
ErrTokenExpired = errors.New("token has expired")
ErrTokenInvalid = errors.New("token is invalid")
j *Jwt
)
type Jwt struct {
cfg *Config
}
// payload
type CustomClaims struct {
jwt.StandardClaims
Sign string `json:"sign"`
}
func Init(c *Config) error {
j = new(Jwt)
if len(c.AesKey) != 32 {
return ErrInvalidConf
}
if len(c.AesIv) != 16 {
return ErrInvalidConf
}
if len(c.Signkey) == 0 {
return ErrInvalidConf
}
j.cfg = c
return nil
}
// CreateToken 生成一个token
func CreateToken(ctx context.Context, b []byte, expiresAt int64) (string, error) {
signStr, err := aesEncrypt(ctx, b)
if err != nil {
qlog.Get().Ctx(ctx).Error(err, string(b))
return "", err
}
if expiresAt == 0 {
// 默认过期时间一天
expiresAt = time.Now().Unix() + 86400
}
claims := CustomClaims{
jwt.StandardClaims{
ExpiresAt: expiresAt,
Issuer: j.cfg.Signkey, //签名的发行者
},
signStr,
}
return jwtCreateToken(ctx, claims)
}
func Parse(ctx context.Context, tokenString string) ([]byte, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(j.cfg.Signkey), nil
})
if err != nil {
qlog.Get().Ctx(ctx).Error(err, tokenString)
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorExpired != 0 {
return nil, ErrTokenExpired
}
}
return nil, err
}
claims, ok := token.Claims.(*CustomClaims)
if !ok {
qlog.Get().Ctx(ctx).Error(err, tokenString)
return nil, ErrTokenInvalid
}
sign := claims.Sign
if len(sign) == 0 {
qlog.Get().Ctx(ctx).Error(err, tokenString, claims)
return nil, ErrTokenInvalid
}
return aesDecrypt(ctx, sign)
}
func ParseTokenWithoutTime(ctx context.Context, tokenString string) ([]byte, error) {
jwt.TimeFunc = func() time.Time {
return time.Unix(0, 0)
}
if len(tokenString) < 10 {
qlog.Get().Ctx(ctx).Error(tokenString)
return nil, ErrTokenInvalid
}
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(j.cfg.Signkey), nil
})
if err != nil {
qlog.Get().Ctx(ctx).Error(tokenString, err)
return nil, err
}
claims, ok := token.Claims.(*CustomClaims)
if !ok {
qlog.Get().Ctx(ctx).Error(tokenString, ok)
return nil, ErrTokenInvalid
}
sign := claims.Sign
if len(sign) == 0 {
qlog.Get().Ctx(ctx).Error(err, tokenString, claims)
return nil, ErrTokenInvalid
}
return aesDecrypt(ctx, sign)
}
func jwtCreateToken(ctx context.Context, claims CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenStr, err := token.SignedString([]byte(j.cfg.Signkey))
if err != nil {
return "", err
}
return tokenStr, nil
}