Skip to content

Instantly share code, notes, and snippets.

@wilhg
Last active April 21, 2023 14:57
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 wilhg/0fa763b6979a478b0f75549f07bd1b1e to your computer and use it in GitHub Desktop.
Save wilhg/0fa763b6979a478b0f75549f07bd1b1e to your computer and use it in GitHub Desktop.
Hertz Auth0 JWT Middleware
package main
import (
"context"
"strings"
"github.com/cloudwego/hertz/pkg/common/hlog"
)
type Claims struct {
Scope string `json:"scope"`
}
func (c *Claims) Validate(ctx context.Context) error {
hlog.Infof("claims scope: %+v", c.Scope)
return nil
}
func (c *Claims) HasScope(expectedScope string) bool {
result := strings.Split(c.Scope, " ")
for i := range result {
if result[i] == expectedScope {
return true
}
}
return false
}
package main
import (
"context"
"errors"
"net/url"
"os"
"strings"
"time"
"github.com/auth0/go-jwt-middleware/v2/jwks"
"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/hlog"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func CheckJwt() app.HandlerFunc {
audiences := []string{os.Getenv("AUTH0_AUDIENCE")}
issuerUrl, err := url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/")
if err != nil {
hlog.Fatalf("Failed to parse the issuer url: %v", err)
}
cacheProvider := jwks.NewCachingProvider(issuerUrl, time.Hour)
jwtValidator, err := validator.New(
cacheProvider.KeyFunc,
validator.RS256,
issuerUrl.String(),
audiences,
validator.WithCustomClaims(func() validator.CustomClaims {
return &Claims{}
}),
validator.WithAllowedClockSkew(time.Minute),
)
if err != nil {
hlog.Fatalf("failed to set up the validator: %v", err)
}
return func(ctx context.Context, c *app.RequestContext) {
token, err := jwtFromHeader("Authorization", "Bearer")(c)
if err != nil {
hlog.Warnf("failed to get token from header: %v", err)
c.AbortWithError(consts.StatusUnauthorized, err)
return
}
claims, err := jwtValidator.ValidateToken(ctx, token)
if err != nil {
hlog.Warnf("failed to validate token: %v", err)
c.AbortWithError(consts.StatusUnauthorized, err)
return
}
c.Set("claims", claims)
c.Next(ctx)
}
}
func jwtFromHeader(header string, authScheme string) func(c *app.RequestContext) (string, error) {
return func(c *app.RequestContext) (string, error) {
auth := c.Request.Header.Get(header)
l := len(authScheme)
if len(auth) > l+1 && strings.EqualFold(auth[:l], authScheme) {
return auth[l+1:], nil
}
return "", errors.New("missing or malformed JWT")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment