Created
January 24, 2023 03:08
-
-
Save erudenko/25c99a3e717a68575e4bdeeff29ec292 to your computer and use it in GitHub Desktop.
JWT Middleware
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JWTMiddleware middleware to handle JWT tokens. | |
func JWTMiddleware(ctx context.Context, jwksURI string, ignorePath []string) func(http.Handler) http.Handler { | |
options := keyfunc.Options{ | |
Ctx: ctx, | |
RefreshErrorHandler: func(err error) { | |
log.Printf("There was an error with the jwt.Keyfunc\nError: %s", err.Error()) | |
}, | |
RefreshInterval: time.Hour, | |
RefreshRateLimit: time.Minute * 5, | |
RefreshTimeout: time.Second * 10, | |
RefreshUnknownKID: true, | |
} | |
// Create the JWKS from the resource at the given URL. | |
jwks, _ := keyfunc.Get(jwksURI, options) | |
ignore := map[string]bool{} | |
for _, p := range ignorePath { | |
ignore[p] = true | |
} | |
return func(next http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
if _, ok := ignore[r.URL.Path]; ok == true { | |
next.ServeHTTP(w, r) | |
return | |
} | |
tokenBytes := extractTokenFromBearerHeader(r.Header.Get(AuthorizationHeaderKey)) | |
if tokenBytes == nil { | |
handlers.WriteJSONError(w, errors.New("token is empty"), http.StatusBadRequest) | |
return | |
} | |
// Parse the JWT. | |
token, err := jwt.Parse(string(tokenBytes), jwks.Keyfunc) | |
if err != nil { | |
handlers.WriteJSONError(w, fmt.Errorf("error parsing JWT token: %s", err.Error()), http.StatusBadRequest) | |
return | |
} | |
// Check if the token is valid. | |
if !token.Valid { | |
handlers.WriteJSONError(w, errors.New("token is invalid"), http.StatusUnauthorized) | |
return | |
} | |
claims, ok := token.Claims.(jwt.MapClaims) | |
if !ok { | |
handlers.WriteJSONError(w, errors.New("token claims type is invalid"), http.StatusInternalServerError) | |
return | |
} | |
ctx := context.WithValue(r.Context(), JWTTokenContextKey, token) | |
ctx = context.WithValue(ctx, JWTTokenClaimsContextKey, claims) | |
next.ServeHTTP(w, r.WithContext(ctx)) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment