-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjwt.go
More file actions
105 lines (83 loc) · 2.31 KB
/
jwt.go
File metadata and controls
105 lines (83 loc) · 2.31 KB
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
package goutil
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
const MainToken = "main-token"
const RefreshToken = "refresh-token"
type RequestCreateJWT struct {
SignMethod jwt.SigningMethod
Key string
Data jwt.MapClaims
}
// CreateJWT is a function for generate token
func CreateJWT(req RequestCreateJWT) (token string, err error) {
if _, ok := req.Data["jti"]; !ok {
req.Data["jti"] = uuid.New().String()
}
// create jwt token
t := jwt.New(req.SignMethod)
t.Claims = req.Data
token, err = t.SignedString([]byte(req.Key))
if err != nil {
return
}
return
}
type KeyContext string
// ParseJWT is a function for parse of token string
func ParseJWT(key string, signMethod jwt.SigningMethod, attributesJWT []string) func(c *gin.Context) {
return func(c *gin.Context) {
errToken := errors.New("token is not valid")
// get value authorization from header
var authorization = c.GetHeader("authorization")
if ok := strings.Contains(authorization, "Bearer "); !ok {
ResponseError(c, http.StatusUnauthorized, errToken, nil)
c.Abort()
return
}
// split value without bearer
authorization = strings.Split(authorization, "Bearer ")[1]
// parse token
token, err := jwt.Parse(authorization, func(token *jwt.Token) (interface{}, error) {
if method, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
} else if method != signMethod {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(key), nil
})
// handle error
if err != nil {
ResponseError(c, http.StatusUnauthorized, errToken, nil)
c.Abort()
return
}
// claim token
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
ResponseError(c, http.StatusUnauthorized, errToken, nil)
c.Abort()
return
}
// set value of token to context
ctx := ParseContext(c)
ctx = context.WithValue(ctx, KeyToken, authorization)
for _, attribute := range attributesJWT {
value, ok := claims[attribute]
if ok {
ctx = context.WithValue(ctx, KeyContext(attribute), value)
}
}
// set up context.Context to gin.Context
c.Set("context", ctx)
// next handler
c.Next()
}
}