package middleware import ( "github.com/golang-jwt/jwt/v5" "github.com/labstack/echo-jwt/v4" "github.com/labstack/echo/v4" ) // JWTConfig defines the config for JWT middleware. type JWTConfig struct { // Skipper defines a function to skip middleware. Skipper Skipper // BeforeFunc defines a function which is executed just before the middleware. BeforeFunc BeforeFunc // SuccessHandler defines a function which is executed for a valid token. SuccessHandler func(c echo.Context) // ErrorHandler defines a function which is executed when all lookups have been done and none of them passed Validator // function. ErrorHandler is executed with last missing (ErrExtractionValueMissing) or an invalid key. // It may be used to define a custom JWT error. // // Note: when error handler swallows the error (returns nil) middleware continues handler chain execution towards handler. // This is useful in cases when portion of your site/api is publicly accessible and has extra features for authorized users // In that case you can use ErrorHandler to set default public JWT token value to request and continue with handler chain. ErrorHandler func(c echo.Context, err error) error // ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandler decides to // ignore the error (by returning `nil`). // This is useful when parts of your site/api allow public access and some authorized routes provide extra functionality. // In that case you can use ErrorHandler to set a default public JWT token value in the request context // and continue. Some logic down the remaining execution chain needs to check that (public) token value then. ContinueOnIgnoredError bool // Context key to store user information from the token into context. // Optional. Default value "user". ContextKey string // Signing key to validate token. // This is one of the three options to provide a token validation key. // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey. // Required if neither user-defined KeyFunc nor SigningKeys is provided. SigningKey any // Map of signing keys to validate token with kid field usage. // This is one of the three options to provide a token validation key. // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey. // Required if neither user-defined KeyFunc nor SigningKey is provided. SigningKeys map[string]any // Signing method used to check the token's signing algorithm. // Optional. Default value HS256. SigningMethod string // KeyFunc defines a user-defined function that supplies the public key for a token validation. // The function shall take care of verifying the signing algorithm and selecting the proper key. // A user-defined KeyFunc can be useful if tokens are issued by an external party. // Used by default ParseTokenFunc implementation. // // When a user-defined KeyFunc is provided, SigningKey, SigningKeys, and SigningMethod are ignored. // This is one of the three options to provide a token validation key. // The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey. // Required if neither SigningKeys nor SigningKey is provided. // Not used if custom ParseTokenFunc is set. // Default to an internal implementation verifying the signing algorithm and selecting the proper key. KeyFunc jwt.Keyfunc // TokenLookup is a string in the form of ":" or ":,:" that is used // to extract token from the request. // Optional. Default value "header:Authorization". // Possible values: // - "header:" or "header::" // `` is argument value to cut/trim prefix of the extracted value. This is useful if header // value has static prefix like `Authorization: ` where part that we // want to cut is ` ` note the space at the end. // In case of JWT tokens `Authorization: Bearer ` prefix we cut is `Bearer `. // If prefix is left empty the whole value is returned. // - "query:" // - "param:" // - "cookie:" // - "form:" // Multiple sources example: // - "header:Authorization:Bearer ,cookie:myowncookie" TokenLookup string // TokenLookupFuncs defines a list of user-defined functions that extract JWT token from the given context. // This is one of the two options to provide a token extractor. // The order of precedence is user-defined TokenLookupFuncs, and TokenLookup. // You can also provide both if you want. TokenLookupFuncs []ValuesExtractor // ParseTokenFunc defines a user-defined function that parses token from given auth. Returns an error when token // parsing fails or parsed token is invalid. // Defaults to implementation using `github.com/golang-jwt/jwt` as JWT implementation library ParseTokenFunc func(c echo.Context, auth string) (any, error) // 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 NewClaimsFunc func(c echo.Context) jwt.Claims } // Errors var ( ErrJWTMissing = echojwt.ErrJWTMissing ErrJWTInvalid = echojwt.ErrJWTInvalid ) func (config *JWTConfig) ToMiddleware() echo.MiddlewareFunc { return echojwt.WithConfig(echojwt.Config{ Skipper: config.Skipper, BeforeFunc: config.BeforeFunc, SuccessHandler: config.SuccessHandler, ErrorHandler: config.ErrorHandler, ContinueOnIgnoredError: config.ContinueOnIgnoredError, ContextKey: config.ContextKey, SigningKey: config.SigningKey, SigningKeys: config.SigningKeys, SigningMethod: config.SigningMethod, KeyFunc: config.KeyFunc, TokenLookup: config.TokenLookup, TokenLookupFuncs: config.TokenLookupFuncs, ParseTokenFunc: config.ParseTokenFunc, NewClaimsFunc: nil, }) } // JWT returns a JSON Web Token (JWT) auth middleware. // // For valid token, it sets the user in context and calls next handler. // For invalid token, it returns "401 - Unauthorized" error. // For missing token, it returns "400 - Bad Request" error. // // See: https://jwt.io/introduction // See `JWTConfig.TokenLookup` // See https://github.com/labstack/echo-jwt func JWT(signingKey any) echo.MiddlewareFunc { return echojwt.JWT(signingKey) }