func KeyAuthWithConfig(config KeyAuthConfig) nio.MiddlewareFunc {
	if config.Skipper == nil {
		config.Skipper = DefaultKeyAuthConfig.Skipper
	}
	if config.AuthScheme == "" {
		config.AuthScheme = DefaultKeyAuthConfig.AuthScheme
	}
	if config.KeyLookup == "" {
		config.KeyLookup = DefaultKeyAuthConfig.KeyLookup
	}
	if config.Validator == nil {
		panic("nio: key-auth middleware requires a validator function")
	}
	parts := strings.Split(config.KeyLookup, ":")
	extractor := keyFromHeader(parts[1], config.AuthScheme)
	switch parts[0] {
	case "query":
		extractor = keyFromQuery(parts[1])
	case "form":
		extractor = keyFromForm(parts[1])
	}
	return func(next nio.HandlerFunc) nio.HandlerFunc {
		return func(c nio.Context) error {
			if config.Skipper(c) {
				return next(c)
			}
			key, err := extractor(c)
			if err != nil {
				return nio.NewHTTPError(http.StatusBadRequest, err.Error())
			}
			valid, err := config.Validator(key, c)
			if err != nil {
				return err
			} else if valid {
				return next(c)
			}
			return nio.ErrUnauthorized
		}
	}
}
KeyAuthWithConfig returns an KeyAuth middleware with config.
See `KeyAuth()`.
package mw
import (
	"errors"
	"net/http"
	"strings"
	"github.com/go-nio/nio"
)
type (
	KeyAuthConfig struct {
		Skipper nio.Skipper
		KeyLookup string `yaml:"key_lookup"`
		AuthScheme string
		Validator KeyAuthValidator
	}
	KeyAuthValidator func(string, nio.Context) (bool, error)
	keyExtractor func(nio.Context) (string, error)
)
var (
	DefaultKeyAuthConfig = KeyAuthConfig{
		Skipper:    nio.DefaultSkipper,
		KeyLookup:  "header:" + nio.HeaderAuthorization,
		AuthScheme: "Bearer",
	}
)
func KeyAuth(fn KeyAuthValidator) nio.MiddlewareFunc {
	c := DefaultKeyAuthConfig
	c.Validator = fn
	return KeyAuthWithConfig(c)
}