forked from micro-plat/hydra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.go
92 lines (85 loc) · 2.41 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
package middleware
import (
"fmt"
"strings"
"time"
"github.com/micro-plat/hydra/conf"
"github.com/micro-plat/hydra/context"
"github.com/micro-plat/hydra/servers/pkg/dispatcher"
"github.com/micro-plat/lib4go/security/jwt"
)
//JwtAuth jwt
func JwtAuth(cnf *conf.MetadataConf) dispatcher.HandlerFunc {
return func(ctx *dispatcher.Context) {
jwtAuth, ok := cnf.GetMetadata("jwt").(*conf.JWTAuth)
if !ok || jwtAuth == nil || jwtAuth.Disable {
ctx.Next()
return
}
//检查jwt.token是否正确
data, err := checkJWT(ctx, jwtAuth.Name, jwtAuth.Secret)
if err == nil {
setJWTRaw(ctx, data)
ctx.Next()
return
}
//不需要校验的URL自动跳过
url := ctx.Request.GetService()
for _, u := range jwtAuth.Exclude {
if u == url {
ctx.Next()
return
}
}
//jwt.token错误,返回错误码
getLogger(ctx).Error(err.GetError())
ctx.AbortWithStatus(err.GetCode())
return
}
}
func setJwtResponse(ctx *dispatcher.Context, cnf *conf.MetadataConf, data interface{}) {
if data == nil {
data = getJWTRaw(ctx)
}
if data == nil {
return
}
jwtAuth, ok := cnf.GetMetadata("jwt").(*conf.JWTAuth)
if !ok || jwtAuth.Disable {
return
}
jwtToken, err := jwt.Encrypt(jwtAuth.Secret, jwtAuth.Mode, data, jwtAuth.ExpireAt)
if err != nil {
ctx.AbortWithError(500, fmt.Errorf("jwt配置出错:%v", err))
return
}
expireTime := time.Now().Add(time.Duration(time.Duration(jwtAuth.ExpireAt)*time.Second - 8*60*60*time.Second))
expireVal := expireTime.Format("Mon, 02 Jan 2006 15:04:05 GMT")
//fmt.Println("jwtToken:", jwtToken)
ctx.Header("Set-Cookie", fmt.Sprintf("%s=%s;path=/;expires=%s;", jwtAuth.Name, jwtToken, expireVal))
ctx.Header(jwtAuth.Name, jwtToken)
}
// CheckJWT 检查jwk参数是否合法
func checkJWT(ctx *dispatcher.Context, name string, secret string) (data interface{}, err context.IError) {
token := getToken(ctx, name)
if token == "" {
return nil, context.NewError(403, fmt.Errorf("%s未传入jwt.token", name))
}
data, er := jwt.Decrypt(token, secret)
if er != nil {
if strings.Contains(er.Error(), "Token is expired") {
return nil, context.NewError(401, er)
}
return data, context.NewError(403, er)
}
return data, nil
}
func getToken(ctx *dispatcher.Context, key string) string {
if cookie, ok := ctx.Request.GetHeader()[key]; ok {
return cookie
}
return ""
}
func setToken(ctx *dispatcher.Context, name string, token string) {
ctx.Header(name, token)
}