Skip to content

Commit

Permalink
add middleware and example
Browse files Browse the repository at this point in the history
  • Loading branch information
satishbabariya committed Apr 10, 2022
1 parent a284266 commit bd9a322
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 0 deletions.
121 changes: 121 additions & 0 deletions auth0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package gofiberauth0middleware

import (
"errors"
"fmt"
"net/url"
"strings"
"time"

"github.com/auth0/go-jwt-middleware/v2/jwks"
"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/gofiber/fiber/v2"
)

type Config struct {
// Filter defines a function to skip middleware.
// Optional. Default: nil
Filter func(*fiber.Ctx) bool

// SuccessHandler defines a function which is executed for a valid token.
// Optional. Default: nil
SuccessHandler fiber.Handler

// ErrorHandler defines a function which is executed for an invalid token.
// It may be used to define a custom JWT error.
// Optional. Default: 401 Invalid or expired JWT
ErrorHandler fiber.ErrorHandler

Issuer string `yaml:"issuer"`
Audience []string `yaml:"audience"`
SignatureAlgorithm string `yaml:"signature_algorithm"`
CacheDuration time.Duration `yaml:"cache_duration"`
}

func makeCfg(config []Config) (cfg Config) {
if len(config) > 0 {
cfg = config[0]
}
if cfg.SuccessHandler == nil {
cfg.SuccessHandler = func(c *fiber.Ctx) error {
return c.Next()
}
}
if cfg.ErrorHandler == nil {
cfg.ErrorHandler = func(c *fiber.Ctx, err error) error {
if err.Error() == "Missing or malformed JWT" {
return c.Status(fiber.StatusBadRequest).SendString("Missing or malformed JWT")
}
return c.Status(fiber.StatusUnauthorized).SendString("Invalid or expired JWT")
}
}

if cfg.CacheDuration == 0 {
cfg.CacheDuration = 5 * time.Minute
}

if cfg.SignatureAlgorithm == "" {
cfg.SignatureAlgorithm = "RS256"
}

return cfg
}

// jwtFromHeader returns a function that extracts token from the request header.
func jwtFromHeader(header string, authScheme string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
auth := c.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")
}
}

func New(config ...Config) fiber.Handler {

cfg := makeCfg(config)

// Return middleware handler
return func(c *fiber.Ctx) error {
// Filter request to skip middleware
if cfg.Filter != nil && cfg.Filter(c) {
return c.Next()
}

issuerURL, err := url.Parse(cfg.Issuer)
if err != nil {
return cfg.ErrorHandler(c, err)
}

provider := jwks.NewCachingProvider(issuerURL, cfg.CacheDuration)

// Set up the validator.
jwtValidator, err := validator.New(
provider.KeyFunc,
validator.SignatureAlgorithm(cfg.SignatureAlgorithm),
issuerURL.String(),
cfg.Audience,
)
if err != nil {
return cfg.ErrorHandler(c, err)
}

token, err := jwtFromHeader("Authorization", "Bearer")(c)
if err != nil {
return cfg.ErrorHandler(c, err)
}

// Get the JWT token from the request header.
claims, err := jwtValidator.ValidateToken(c.Context(), token)
if err != nil {
fmt.Println(err)
return cfg.ErrorHandler(c, err)
}

// Store user information from token into context.
c.Locals("claims", claims)
return cfg.SuccessHandler(c)
}
}
2 changes: 2 additions & 0 deletions example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
AUTH0_AUDIENCE=https://example.auth0.com/api/v2/
AUTH0_ISSUER=https://example.auth0.com/
30 changes: 30 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"log"
"net/http"
"os"

"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/gofiber/fiber/v2"
auth0 "github.com/satishbabariya/go-fiber-auth0-middleware"
)

func main() {
app := fiber.New()

app.Use(auth0.New(auth0.Config{
Issuer: os.Getenv("AUTH0_ISSUER"),
Audience: []string{os.Getenv("AUTH0_AUDIENCE")},
ErrorHandler: func(c *fiber.Ctx, err error) error {
return fiber.NewError(http.StatusUnauthorized, err.Error())
},
}))

app.Get("/", func(c *fiber.Ctx) error {
claims := c.Locals("claims").(*validator.ValidatedClaims)
return c.JSON(claims)
})

log.Fatal(app.Listen(":1203"))
}
20 changes: 20 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module github.com/satishbabariya/go-fiber-auth0-middleware

go 1.18

require (
github.com/auth0/go-jwt-middleware/v2 v2.0.1
github.com/gofiber/fiber/v2 v2.31.0
)

require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/klauspost/compress v1.15.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.34.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
)
39 changes: 39 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/auth0/go-jwt-middleware/v2 v2.0.1 h1:zAgDKL7nsfVBFl31GGxsSXkhuRzYe1fVtJcO3aMSrFU=
github.com/auth0/go-jwt-middleware/v2 v2.0.1/go.mod h1:kDt7JgUuDEp1VutfUmO4ZxBLL51vlNu/56oDfXc5E0Y=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/gofiber/fiber/v2 v2.31.0 h1:M2rWPQbD5fDVAjcoOLjKRXTIlHesI5Eq7I5FEQPt4Ow=
github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4=
github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

0 comments on commit bd9a322

Please sign in to comment.