func selectGetKeyFunc(method jwt.SigningMethod) func(jwt.SigningMethod) (interface{}, error) {
	switch method.(type) {
	case *jwt.SigningMethodRSA:
		return GetKeyRSA
	case *jwt.SigningMethodECDSA:
		return GetKeyECDSA
	case *jwt.SigningMethodRSAPSS:
		return GetKeyRSAPSS
	default:
		return GetHMACKey
	}
}
selectGetKeyFunc is an helper function to choose the GetKey function
according to the Signing method used
package tokenauth
import (
	"io/ioutil"
	"log"
	"net/http"
	"github.com/dgrijalva/jwt-go"
	"github.com/gobuffalo/buffalo"
	"github.com/gobuffalo/envy"
	"github.com/pkg/errors"
)
var (
	ErrTokenInvalid = errors.New("token invalid")
	ErrNoToken = errors.New("token not found in request")
	ErrBadSigningMethod = errors.New("unexpected signing method")
)
type Options struct {
	SignMethod jwt.SigningMethod
	GetKey     func(jwt.SigningMethod) (interface{}, error)
	AuthScheme string
}
func New(options Options) buffalo.MiddlewareFunc {
	if options.SignMethod == nil {
		options.SignMethod = jwt.SigningMethodHS256
	}
	if options.GetKey == nil {
		options.GetKey = selectGetKeyFunc(options.SignMethod)
	}
	key, err := options.GetKey(options.SignMethod)
	if err != nil {
		log.Fatal(errors.Wrap(err, "couldn't get key"))
	}
	if options.AuthScheme == "" {
		options.AuthScheme = "Bearer"
	}
	return func(next buffalo.Handler) buffalo.Handler {
		return func(c buffalo.Context) error {
			authString := c.Request().Header.Get("Authorization")
			tokenString, err := getJwtToken(authString, options.AuthScheme)
			if err != nil {
				return c.Error(http.StatusUnauthorized, err)
			}
			token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
				if token.Method.Alg() != options.SignMethod.Alg() {
					return nil, ErrBadSigningMethod
				}
				return key, nil
			})
			if err != nil {
				return c.Error(http.StatusUnauthorized, err)
			}
			c.Set("claims", token.Claims)
			err = next(c)
			return err
		}
	}
}