go项目脚手架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
6.3 KiB

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 "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used
// to extract token from the request.
// Optional. Default value "header:Authorization".
// Possible values:
// - "header:<name>" or "header:<name>:<cut-prefix>"
// `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header
// value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we
// want to cut is `<auth-scheme> ` note the space at the end.
// In case of JWT tokens `Authorization: Bearer <token>` prefix we cut is `Bearer `.
// If prefix is left empty the whole value is returned.
// - "query:<name>"
// - "param:<name>"
// - "cookie:<name>"
// - "form:<name>"
// 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)
}