Skip to content

Add ParserOption support. #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ type Config struct {
// Defaults to implementation using `github.com/golang-jwt/jwt` as JWT implementation library
ParseTokenFunc func(c echo.Context, auth string) (interface{}, error)

// ParserOption defines a list of options that are passed to the JWT parser.
// This is used to configure the parser behavior, such as whether to validate the token's expiration time,
// whether to validate the token's audience, etc.
// Optional. Default value is empty slice.
ParserOption []jwt.ParserOption

// Claims are extendable claims data defining token content. Used by default ParseTokenFunc implementation.
// Not used if custom ParseTokenFunc is set.
// Optional. Defaults to function returning jwt.MapClaims
Expand Down Expand Up @@ -286,7 +292,7 @@ func (config Config) defaultKeyFunc(token *jwt.Token) (interface{}, error) {
//
// error returns TokenError.
func (config Config) defaultParseTokenFunc(c echo.Context, auth string) (interface{}, error) {
token, err := jwt.ParseWithClaims(auth, config.NewClaimsFunc(c), config.KeyFunc)
token, err := jwt.ParseWithClaims(auth, config.NewClaimsFunc(c), config.KeyFunc, config.ParserOption...)
if err != nil {
return nil, &TokenError{Token: token, Err: err}
}
Expand Down
53 changes: 53 additions & 0 deletions jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"strings"
"testing"
"time"

"github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4"
Expand Down Expand Up @@ -628,6 +629,58 @@ func TestConfig_custom_ParseTokenFunc_Keyfunc(t *testing.T) {
assert.Equal(t, http.StatusTeapot, res.Code)
}

func TestConfig_parseOptions(t *testing.T) {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusTeapot, "test")
})

signingKey := []byte("secret")
expiredClaim := jwt.MapClaims{
"admin": true,
"name": "John Doe",
"sub": "1234567890",
"exp": time.Now().Add(-10 * time.Second).Unix(), // expired 10 seconds ago
}
testClaim := jwt.MapClaims{
"admin": true,
"name": "John Doe",
"sub": "1234567890",
"exp": time.Now().Add(-2 * time.Second).Unix(),
}

expiredToken := jwt.NewWithClaims(jwt.SigningMethodHS256, expiredClaim)
expiredTokenString, err := expiredToken.SignedString(signingKey)
if err != nil {
t.Fatalf("failed to sign expired token: %v", err)
}

testToken := jwt.NewWithClaims(jwt.SigningMethodHS256, testClaim)
testTokenString, err := testToken.SignedString(signingKey)
if err != nil {
t.Fatalf("failed to sign test token: %v", err)
}

config := Config{
SigningKey: signingKey,
ParserOption: []jwt.ParserOption{jwt.WithLeeway(5 * time.Second)}, // allow 5 seconds leeway for token expiration
}

e.Use(WithConfig(config))

req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set(echo.HeaderAuthorization, "Bearer "+expiredTokenString)
res := httptest.NewRecorder()
e.ServeHTTP(res, req)
assert.Equal(t, http.StatusUnauthorized, res.Code)

req = httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set(echo.HeaderAuthorization, "Bearer "+testTokenString)
res = httptest.NewRecorder()
e.ServeHTTP(res, req)
assert.Equal(t, http.StatusTeapot, res.Code)
}

func TestMustJWTWithConfig_SuccessHandler(t *testing.T) {
e := echo.New()

Expand Down