-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwtauth.go
146 lines (125 loc) · 3.55 KB
/
jwtauth.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Package jwtauth
//
// @author: xwc1125
package jwtauth
import (
"fmt"
"net/http"
"sync"
"github.com/dgrijalva/jwt-go"
"github.com/xwc1125/xwc1125-pkg/protocol/contextx"
"github.com/xwc1125/xwc1125-pkg/types/response"
)
type (
// TokenExtractor is a function that takes a context as input and returns
// either a token or an error. An error should only be returned if an attempt
// to specify a token was found, but the information was somehow incorrectly
// formed. In the case where a token is simply not present, this should not
// be treated as an error. An empty string should be returned in that case.
TokenExtractor func(req *http.Request) (string, error)
MapClaims jwt.MapClaims
)
var (
jwtAuth *JwtAuth
lock sync.Mutex
Issuer = "key-casbins-jwt"
)
// JwtAuth jwt auth
type JwtAuth struct {
JWTConfig JWTConfig
*JwtHandler
Extractor TokenExtractor // Extractor 从请求中提取令牌的函数
}
// NewJwtAuth jwt中间件配置
func NewJwtAuth(config JWTConfig) *JwtAuth {
if jwtAuth != nil {
return jwtAuth
}
lock.Lock()
defer lock.Unlock()
if jwtAuth != nil {
return jwtAuth
}
jwtHandler := getJwtHandler(config)
defer jwtHandler.Release()
tokenExtractors := make([]TokenExtractor, 0)
if len(config.AuthorizationKey) == 0 {
tokenExtractors = append(tokenExtractors, FromAuthHeader(AuthorizationKEY))
} else {
tokenExtractors = append(tokenExtractors, FromAuthHeader(config.AuthorizationKey))
}
if len(config.ParamTokenKey) > 0 {
tokenExtractors = append(tokenExtractors, FromParameter(config.ParamTokenKey))
}
if len(config.CookieTokenKey) > 0 {
tokenExtractors = append(tokenExtractors, FromCookie(config.CookieTokenKey))
}
jwtAuth = &JwtAuth{
JWTConfig: config,
JwtHandler: jwtHandler,
Extractor: FromFirst(tokenExtractors...),
}
return jwtAuth
}
// GenerateToken 在登录成功的时候生成token
func (m *JwtAuth) GenerateToken(userId int64, userName string, extraData MapClaims) (string, error) {
return GenerateToken(m.JWTConfig, userId, userName, extraData)
}
// CheckJWT 验证jwt
func (m *JwtAuth) CheckJWT(ctx contextx.Context) (*UserToken, error) {
if !m.JWTConfig.EnableAuthOnOptions {
if ctx.Request().Method == response.MethodOptions {
return nil, TokenUnsupportedOptions
}
}
// 获取token
var (
token string
err error
)
token, err = m.Extractor(ctx.Request())
if err != nil {
m.logf("error extracting JWT: %v", err)
return nil, fmt.Errorf("error extracting token: %v", err)
}
if token == "" {
m.logf("Error: No credentials found")
return nil, fmt.Errorf(TokenParseFailedAndEmpty)
}
jwtClaims, err := ParseToken(m.JWTConfig, token)
if err != nil {
return nil, err
}
ctx.Set(m.JWTConfig.JwtContextKey+"_raw", token)
return &jwtClaims.UserToken, nil
}
// logf 打印日志
func (m *JwtAuth) logf(format string, args ...interface{}) {
if m.JWTConfig.Debug {
log().Debug(fmt.Sprintf(format, args...))
}
}
func Serve(ctx contextx.Context, config JWTConfig) (userToken *UserToken, b bool) {
NewJwtAuth(config)
var err error
if userToken, err = jwtAuth.CheckJWT(ctx); err != nil {
log().Error("Check jwt error", "err", err)
return userToken, false
}
return userToken, true
}
func CheckPermission(ctx contextx.Context, config JWTConfig) bool {
NewJwtAuth(config)
if _, err := jwtAuth.CheckJWT(ctx); err != nil {
log().Error("Check jwt error", "err", err)
return false
}
return true
}
func GetUserId(config JWTConfig, token string) (int64, bool) {
userToken, _ := ParseToken(config, token)
if userToken != nil {
return userToken.Uid, true
}
return -1, false
}