package fuphttp import ( "crypto/subtle" "fmt" "net/http" "github.com/gorilla/mux" ) func TokenAuthMiddleware(token, realm string) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { if token == "" { return next } tokenBytes := []byte(token) return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() if !IsMutate(ctx) { // Allow all access to public pages. next.ServeHTTP(rw, r) return } requestAuth := func(s string) { rw.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q, charset=\"UTF-8\"", realm)) http.Error(rw, s, http.StatusUnauthorized) } // Check for basic auth, first. _, pw, ok := r.BasicAuth() switch { case !ok: requestAuth("unparsable or no credentials") return case subtle.ConstantTimeCompare([]byte(pw), tokenBytes) != 1: requestAuth("bad credentials") return } // Auth check passed, let's go. next.ServeHTTP(rw, r) return }) } }