-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.go
107 lines (99 loc) · 2.97 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
package middleware
import (
"context"
"fmt"
"net/http"
"time"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/errors"
"github.com/cloudwego/hertz/pkg/common/hlog"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/hertz-contrib/jwt"
"github.com/three-body/hertz-scaffold/biz/hmodel/user"
"github.com/three-body/hertz-scaffold/biz/logic"
)
var (
JwtMiddleware *jwt.HertzJWTMiddleware
IdentityKey = "identityKey"
)
func init() {
var err error
JwtMiddleware, err = jwt.New(&jwt.HertzJWTMiddleware{
Realm: "hertz jwt",
Key: []byte("secret key"),
Timeout: time.Hour * 24 * 7,
MaxRefresh: time.Hour * 24 * 7,
TokenLookup: "header: Authorization, query: token, cookie: jwt",
TokenHeadName: "Bearer",
IdentityKey: IdentityKey,
IdentityHandler: func(ctx context.Context, c *app.RequestContext) interface{} {
claims := jwt.ExtractClaims(ctx, c)
return claims
},
// triggered when login succeed. save token data
PayloadFunc: func(data interface{}) jwt.MapClaims {
if v, ok := data.(*user.User); ok {
return jwt.MapClaims{
"uid": v.UID,
"nickname": v.Nickname,
}
}
return jwt.MapClaims{}
},
Authenticator: authenticator,
LoginResponse: loginRespHandler,
LogoutResponse: logoutRespHandler,
Authorizator: func(data interface{}, ctx context.Context, c *app.RequestContext) bool {
if v, ok := data.(jwt.MapClaims); ok && v["uid"] != "" {
return true
}
return false
},
HTTPStatusMessageFunc: func(e error, ctx context.Context, c *app.RequestContext) string {
hlog.CtxErrorf(ctx, "jwt biz err = %+v", e.Error())
return e.Error()
},
Unauthorized: func(ctx context.Context, c *app.RequestContext, code int, message string) {
c.JSON(code, utils.H{
"code": code,
"message": message,
})
},
})
if err != nil {
panic(fmt.Errorf("init JWT failed: %w", err))
}
}
func authenticator(ctx context.Context, c *app.RequestContext) (interface{}, error) {
var req user.LoginRequest
if err := c.BindAndValidate(&req); err != nil {
return nil, errors.NewPublic(err.Error()).SetMeta(jwt.ErrFailedAuthentication)
}
if err := req.IsValid(); err != nil {
return nil, errors.NewPublic(err.Error()).SetMeta(jwt.ErrMissingLoginValues)
}
user, err := logic.NewUserLogic(ctx, c).Login(&req)
if err != nil {
return nil, errors.NewPublic(err.Error()).SetMeta(jwt.ErrFailedAuthentication)
}
return user, nil
}
// loginRespHandler .
func loginRespHandler(ctx context.Context, c *app.RequestContext, code int, token string, expire time.Time) {
if code == http.StatusOK {
c.JSON(http.StatusOK, user.LoginResponse{
Token: token,
Expire: expire.Format(time.RFC3339),
})
} else {
c.JSON(code, user.LogoutResponse{})
}
}
// logoutRespHandler .
func logoutRespHandler(ctx context.Context, c *app.RequestContext, code int) {
if code == http.StatusOK {
c.JSON(http.StatusOK, user.LogoutResponse{})
} else {
c.JSON(code, user.LogoutResponse{})
}
}