diff --git a/middleware/jwt.go b/middleware/jwt.go index 8432cef7..7f811989 100644 --- a/middleware/jwt.go +++ b/middleware/jwt.go @@ -35,6 +35,10 @@ type ( // - "header:" // - "query:" TokenLookup string `json:"token_lookup"` + + // Claims are extendable claims data defining token content. + // Optional. Default value jwt.MapClaims + Claims jwt.Claims } jwtExtractor func(echo.Context) (string, error) @@ -56,6 +60,7 @@ var ( SigningMethod: AlgorithmHS256, ContextKey: "user", TokenLookup: "header:" + echo.HeaderAuthorization, + Claims: jwt.MapClaims{}, } ) @@ -91,6 +96,9 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { if config.TokenLookup == "" { config.TokenLookup = DefaultJWTConfig.TokenLookup } + if config.Claims == nil { + config.Claims = DefaultJWTConfig.Claims + } // Initialize parts := strings.Split(config.TokenLookup, ":") @@ -110,7 +118,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc { if err != nil { return echo.NewHTTPError(http.StatusBadRequest, err.Error()) } - token, err := jwt.Parse(auth, func(t *jwt.Token) (interface{}, error) { + token, err := jwt.ParseWithClaims(auth, config.Claims, func(t *jwt.Token) (interface{}, error) { // Check the signing method if t.Method.Alg() != config.SigningMethod { return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"]) diff --git a/middleware/jwt_test.go b/middleware/jwt_test.go index e35e6d3e..cd2518c6 100644 --- a/middleware/jwt_test.go +++ b/middleware/jwt_test.go @@ -10,6 +10,18 @@ import ( "github.com/stretchr/testify/assert" ) +// CustomInfo defines some custom types we're going to use within our tokens +type CustomInfo struct { + Name string `json:"name"` + Admin bool `json:"admin"` +} + +// MyCustomClaims are custom claims expanding default ones +type MyCustomClaims struct { + *jwt.StandardClaims + CustomInfo +} + func TestJWT(t *testing.T) { e := echo.New() req := test.NewRequest(echo.GET, "/", nil) @@ -49,9 +61,23 @@ func TestJWT(t *testing.T) { assert.Equal(t, claims["name"], "John Doe") } + // Valid JWT with custom claims + config = JWTConfig{ + Claims: &MyCustomClaims{}, + SigningKey: []byte("secret"), + } + h = JWTWithConfig(config)(handler) + if assert.NoError(t, h(c)) { + user := c.Get("user").(*jwt.Token) + claims := user.Claims.(*MyCustomClaims) + assert.Equal(t, claims.Name, "John Doe") + assert.Equal(t, claims.Admin, true) + } + // Invalid Authorization header req.Header().Set(echo.HeaderAuthorization, "invalid-auth") h = JWT([]byte("secret"))(handler) he = h(c).(*echo.HTTPError) assert.Equal(t, http.StatusBadRequest, he.Code) + }