Skip to content

Instantly share code, notes, and snippets.

@erudenko
Created January 24, 2023 03:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erudenko/25c99a3e717a68575e4bdeeff29ec292 to your computer and use it in GitHub Desktop.
Save erudenko/25c99a3e717a68575e4bdeeff29ec292 to your computer and use it in GitHub Desktop.
JWT Middleware
// 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