-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjwt.go
99 lines (70 loc) · 2.36 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
package goway_jwt_handler
import (
"regexp"
"net/http"
"errors"
"github.com/dgrijalva/jwt-go"
"github.com/andrepinto/goway/router"
. "github.com/andrepinto/goway/handlers"
)
//noinspection GoUnusedConst
const NAME = "AUTHENTICATION"
var regexpBearer = regexp.MustCompile("^Bearer\\s([A-Za-z0-9\\-\\._~\\+\\/]+=*)$")
type OpCallback func ( *router.Route, *http.Request, *jwt.MapClaims ) *HandlerError
type ErrCallback func ( *router.Route, *http.Request, *HandlerError) *HandlerError
//noinspection GoUnusedParameter
func opCallback( route *router.Route, r *http.Request, claim *jwt.MapClaims ) *HandlerError { return nil }
//noinspection GoUnusedParameter
func errCallback( route *router.Route, r *http.Request, err *HandlerError) *HandlerError {
return err
}
type JWTHandler struct {
Secret string
Algorithm *jwt.SigningMethodHMAC
OnSuccess OpCallback
OnError ErrCallback
}
//noinspection GoUnusedExportedFunction
func NewJWTHandler( secret string, algorithm *jwt.SigningMethodHMAC ) (*JWTHandler) {
return &JWTHandler{
Secret: secret,
Algorithm: algorithm,
OnSuccess: opCallback,
OnError: errCallback,
}
}
func ( handler *JWTHandler ) validateSignature(token *jwt.Token) (interface{}, error) {
//@TODO validate against handler.Algorithm
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("Invalid token.")
}
return []byte(handler.Secret), nil
}
func (handler *JWTHandler) decode(tk string) (*jwt.MapClaims, error) {
var claims jwt.MapClaims
var err error
var ok bool
token, err := jwt.Parse(tk, handler.validateSignature)
if ( err != nil ) {
return nil, err
}
claims, ok = token.Claims.(jwt.MapClaims);
if (!ok) {
return nil, errors.New("Token is invalid")
}
return &claims, nil
}
func (handler *JWTHandler) Handle(route *router.Route, req *http.Request) (*HandlerError){
matches := regexpBearer.FindStringSubmatch(req.Header.Get("Authorization"))
if ( len(matches) != 2 ) {
return handler.OnError( route, req, NewHttpError( http.StatusUnauthorized, "Unauthorized"))
}
claim, err := handler.decode(matches[1])
if (err != nil) {
return handler.OnError( route, req, NewHttpError( http.StatusUnauthorized, err.Error()))
}
if err := claim.Valid(); err != nil {
return handler.OnError( route, req, NewHttpError( http.StatusUnauthorized, err.Error()))
}
return handler.OnSuccess( route, req, claim )
}