1
0
mirror of https://github.com/labstack/echo.git synced 2024-11-28 08:38:39 +02:00

Add HandleEmptyToken to JWT middleware

Now it is possible to add custom handler for missing JWT.
This commit is contained in:
Przemek Komosa 2016-07-02 00:55:11 +02:00
parent bb6baa2088
commit ae09482493
2 changed files with 46 additions and 4 deletions

View File

@ -32,6 +32,10 @@ type (
// - "header:<name>"
// - "query:<name>"
TokenLookup string `json:"token_lookup"`
// HandleEmptyToken is handler executed when there is no token.
// It could be used for redirection.
HandleEmptyToken echo.HandlerFunc
}
jwtExtractor func(echo.Context) (string, error)
@ -52,7 +56,12 @@ var (
SigningMethod: AlgorithmHS256,
ContextKey: "user",
TokenLookup: "header:" + echo.HeaderAuthorization,
HandleEmptyToken: func(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, errJWTEmptyToken.Error())
},
}
errJWTEmptyToken = errors.New("empty jwt")
)
// JWT returns a JSON Web Token (JWT) auth middleware.
@ -84,6 +93,9 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.TokenLookup == "" {
config.TokenLookup = DefaultJWTConfig.TokenLookup
}
if config.HandleEmptyToken == nil {
config.HandleEmptyToken = DefaultJWTConfig.HandleEmptyToken
}
// Initialize
parts := strings.Split(config.TokenLookup, ":")
@ -97,6 +109,9 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
return func(c echo.Context) error {
auth, err := extractor(c)
if err != nil {
if err == errJWTEmptyToken {
return config.HandleEmptyToken(c)
}
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
token, err := jwt.Parse(auth, func(t *jwt.Token) (interface{}, error) {
@ -122,11 +137,15 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
func jwtFromHeader(header string) jwtExtractor {
return func(c echo.Context) (string, error) {
auth := c.Request().Header().Get(header)
lenAuth := len(auth)
if lenAuth == 0 {
return "", errJWTEmptyToken
}
l := len(bearer)
if len(auth) > l+1 && auth[:l] == bearer {
if lenAuth > l+1 && auth[:l] == bearer {
return auth[l+1:], nil
}
return "", errors.New("empty or invalid jwt in authorization header")
return "", errors.New("invalid jwt in authorization header")
}
}
@ -135,9 +154,10 @@ func jwtFromHeader(header string) jwtExtractor {
func jwtFromQuery(param string) jwtExtractor {
return func(c echo.Context) (string, error) {
token := c.QueryParam(param)
var err error
if token == "" {
return "", errors.New("empty jwt in query param")
err = errJWTEmptyToken
}
return token, nil
return token, err
}
}

View File

@ -19,6 +19,9 @@ func TestJWT(t *testing.T) {
validKey := []byte("secret")
invalidKey := []byte("invalid-key")
validAuth := bearer + " " + token
redirect := func(c echo.Context) error {
return echo.NewHTTPError(http.StatusFound, "redirect")
}
for _, tc := range []struct {
expPanic bool
@ -60,6 +63,15 @@ func TestJWT(t *testing.T) {
expErrCode: http.StatusBadRequest,
info: "Empty header auth field",
},
{
config: JWTConfig{
SigningKey: validKey,
HandleEmptyToken: redirect,
},
hdrAuth: "",
expErrCode: http.StatusFound,
info: "Empty header auth field with redirect",
},
{
config: JWTConfig{
SigningKey: validKey,
@ -95,6 +107,16 @@ func TestJWT(t *testing.T) {
expErrCode: http.StatusBadRequest,
info: "Empty query",
},
{
config: JWTConfig{
SigningKey: validKey,
TokenLookup: "query:jwt",
HandleEmptyToken: redirect,
},
reqURL: "/?a=b",
expErrCode: http.StatusFound,
info: "Empty query with redirect",
},
} {
if tc.reqURL == "" {