-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjwt.go
66 lines (53 loc) · 2.23 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
package middleware
import (
"context"
"fmt"
"net/http"
"strings"
"github.com/dgrijalva/jwt-go"
)
// Condition is a callback that allows you to add further checks.
type Condition func(claims *Claims, r *http.Request) bool
// JWTAuthenticate is a JWT Authentication middleware operation.
func (m *Middleware) JWTAuthenticate(w http.ResponseWriter, r *http.Request) bool {
// Attempt to get token string from the Authorization header
token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
// Attempt to parse the token
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return m.Options.JWTKey, nil
})
if err != nil || !parsedToken.Valid {
m.ResolveJSONError(w, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), "Access to the requested resource is denied")
return false
}
// Setting the access token in the request context.
*r = *r.WithContext(context.WithValue(r.Context(), m.Options.JWTContextKey, parsedToken))
return true
}
// JWTAuthorize is an authorization middleware operation.
func (m *Middleware) JWTAuthorize(permissions []string, conditions ...Condition) Operation {
return func(w http.ResponseWriter, r *http.Request) bool {
// Attempting to get access token claims from the request context
claims := NewClaims(r.Context().Value(m.Options.JWTContextKey))
if claims == nil {
m.ResolveJSONError(w, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), "Access to the requested resource is denied")
return false
}
// Checking if the access token claims contains at least one of the required permission
if !claims.HasPermissions(permissions, false) {
m.ResolveJSONError(w, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), "Access to the requested resource is denied")
return false
}
// Check if all conditions are satisfied
for _, condition := range conditions {
if !condition(claims, r) {
m.ResolveJSONError(w, http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), "Access to the requested resource is denied")
return false
}
}
return true
}
}