-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
jwt_auth.go
139 lines (116 loc) · 3.86 KB
/
jwt_auth.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
package gateway
import (
"errors"
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
// VerifyJWT giving a jwt token and a secret it validates the token against a hard coded TokenClaims struct
func VerifyJWT(tokenString string, secret []byte) (*TokenClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return secret, nil
})
// a user might had submitted a non-jwt token
// if err != nil {
// return nil, err
// }
if claims, ok := token.Claims.(*TokenClaims); ok && token.Valid {
return claims, nil
} else {
return nil, err
}
}
func verifyWithClaim(tokenString string, secret []byte) error {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if token.Valid {
fmt.Println("You look nice today")
} else if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return errors.New("That's not even a token")
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
// Token is either expired or not active yet
return errors.New("Timing is everything")
} else {
return errors.New("Couldn't handle this token:")
}
} else {
return errors.New("Couldn't handle this token")
}
return nil
}
// GenerateJWT generates a JWT standard token with default values hardcoded. FIXME
func GenerateJWT(serviceID string, secret []byte) (string, error) {
// Create a new token object, specifying signing method and the claims
// you would like it to contain.
expiresAt := time.Now().Add(time.Hour * 1000).UTC().Unix()
claims := TokenClaims{
serviceID,
jwt.StandardClaims{
ExpiresAt: expiresAt,
Issuer: "noebs",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Sign and get the complete encoded token as a string using the secret
if tokenString, err := token.SignedString(secret); err == nil {
fmt.Println(tokenString)
return tokenString, nil
} else {
return "", err
}
}
// GenerateJWTWithClaim generates a JWT standard token with default values hardcoded. FIXME
func GenerateJWTWithClaim(username string, secret []byte, tk TokenClaims) (string, error) {
// Create a new token object, specifying signing method and the claims
// you would like it to contain.
t := tk.Default(username)
token := jwt.NewWithClaims(jwt.SigningMethodHS256, t)
// Sign and get the complete encoded token as a string using the secret
if tokenString, err := token.SignedString(secret); err == nil {
fmt.Println(tokenString)
return tokenString, nil
} else {
return "", err
}
}
func generateClaims(iat, eat int64, issuer string) jwt.StandardClaims {
claims := jwt.StandardClaims{
IssuedAt: iat,
ExpiresAt: eat,
Issuer: issuer,
}
return claims
}
// TokenClaims noebs standard claim
type TokenClaims struct {
Username string `json:"username"`
jwt.StandardClaims
}
// Default populate token claims with default values
func (t TokenClaims) Default(username string) jwt.Claims {
n := time.Now().Unix()
n3h := time.Now().Add(3 * time.Hour).Unix()
t.StandardClaims = generateClaims(n, n3h, username)
t.Username = username
return t
}
//secretFromClaims returns the claim's secret. in this case it is a user name
func secretFromClaims(token string, skipTime bool) (string, error) {
claims, err := VerifyJWT(token, jwtKey)
if e, ok := err.(*jwt.ValidationError); ok {
if e.Errors&jwt.ValidationErrorExpired > 0 && skipTime {
return claims.Username, nil
} else {
return "", errors.New("token is invalid")
}
} else {
return "", errors.New("token is invalid")
}
}