func AuhtorizationHandler(scope string, h httprouter.Handle) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		token, err := GetToken(r)
		if err != nil {
			AddAuthenticateHeader(w, err, scope)
			statusHandler(err.Error(), http.StatusUnauthorized, w)
			return
		}
		var allScope string
		if scope != "" {
			allScope = fmt.Sprintf("%s:all", strings.SplitN(scope, ":", 2)[0])
		}
		claims, err := VerifyToken(token)
		if err != nil {
			AddAuthenticateHeader(w, err, scope, allScope)
			statusHandler(err.Error(), http.StatusUnauthorized, w)
			return
		}
		var ok bool
		if scope == "" {
			ok = true
		} else {
			for _, s := range claims.Scope {
				if s == scope || s == allScope {
					ok = true
					break
				}
			}
		}
		if !ok {
			AddAuthenticateHeader(w, ErrInvalidScope, scope, allScope)
			statusHandler("Insufficient permissions", http.StatusForbidden, w)
			return
		}
		h(w, r, ps)
	}
}
AuhtorizationHandler returns a JWT authorization handler
package jwt
import (
	"errors"
	"fmt"
	"net/http"
	"strings"
	"time"
	"github.com/tarkov-database/rest-api/model"
	"github.com/tarkov-database/rest-api/view"
	"github.com/gbrlsnchs/jwt/v3"
	"github.com/julienschmidt/httprouter"
)
var (
	ErrInvalidScope = errors.New("no or invalid scopes")
	ErrInvalidSubject = errors.New("invalid subject")
	ErrInvalidAudience = errors.New("audience mismatch")
	ErrExpiredToken = errors.New("token is expired")
	ErrNotBefore = errors.New("token is not yet valid")
	ErrMalformed = errors.New("token is malformed")
	ErrInvalidToken = errors.New("token is invalid")
)
var (
	ErrNoAuthHeader = errors.New("authorization header not set")
	ErrInvalidAuthHeader = errors.New("invalid authorization header")
)
const (
	ScopeAllRead = "read:all"
	ScopeAllWrite = "write:all"
	ScopeItemRead = "read:item"
	ScopeItemWrite = "write:item"
	ScopeHideoutRead = "read:hideout"
	ScopeHideoutWrite = "write:hideout"
	ScopeLocationRead = "read:location"
	ScopeLocationWrite = "write:location"
	ScopeUserRead = "read:user"
	ScopeUserWrite = "write:user"
	ScopeTokenWrite = "write:token"
)
func isScopeValid(s string) bool {
	var valid bool
	switch s {
	case ScopeAllRead:
		valid = true
	case ScopeAllWrite:
		valid = true
	case ScopeItemRead:
		valid = true
	case ScopeItemWrite:
		valid = true
	case ScopeHideoutRead:
		valid = true
	case ScopeHideoutWrite:
		valid = true
	case ScopeLocationRead:
		valid = true
	case ScopeLocationWrite:
		valid = true
	case ScopeUserRead:
		valid = true
	case ScopeUserWrite:
		valid = true
	case ScopeTokenWrite:
		valid = true
	}
	return valid
}
type Claims struct {
	jwt.Payload
	Scope []string `json:"scope"`
}
func (c *Claims) ValidateCustom() error {
	for _, s := range c.Scope {
		if !isScopeValid(s) {
			return ErrInvalidScope
		}
	}
	return nil
}
func CreateToken(c *Claims, d *time.Duration) (string, error) {
	now := time.Now()
	c.Audience = cfg.Audience
	c.IssuedAt = jwt.NumericDate(now)
	if d != nil {
		c.ExpirationTime = jwt.NumericDate(now.Add(*d))
	} else {
		c.ExpirationTime = jwt.NumericDate(now.Add(cfg.ExpirationTime))
	}
	t, err := jwt.Sign(c, cfg.Algorithm)
	if err != nil {
		return "", err
	}
	return string(t), nil
}
func GetToken(r *http.Request) (string, error) {
	header := r.Header.Get("Authorization")
	if len(header) == 0 {
		return "", ErrNoAuthHeader
	}
	headerStr := strings.TrimSpace(header)
	if !strings.HasPrefix(header, "Bearer ") {
		return "", ErrInvalidAuthHeader
	}
	return strings.TrimPrefix(headerStr, "Bearer "), nil
}
func VerifyToken(tokenStr string) (*Claims, error) {
	claims := &Claims{}
	now := time.Now()
	expVal := jwt.ExpirationTimeValidator(now.Add(-cfg.Leeway))
	audVal := jwt.AudienceValidator(cfg.Audience)
	valPayload := jwt.ValidatePayload(&claims.Payload, expVal, audVal)
	if _, err := jwt.Verify([]byte(tokenStr), cfg.Algorithm, claims, valPayload); err != nil {
		switch err {
		case jwt.ErrExpValidation:
			return claims, ErrExpiredToken
		case jwt.ErrNbfValidation:
			return claims, ErrNotBefore
		case jwt.ErrAudValidation:
			return claims, ErrInvalidAudience
		case jwt.ErrSubValidation:
			return claims, ErrInvalidSubject
		case jwt.ErrMalformed:
			return claims, ErrMalformed
		default:
			return claims, ErrInvalidToken
		}
	}
	return claims, nil
}