github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/middlewares/auth.go (about) 1 package middlewares 2 3 import ( 4 "net/http" 5 6 "golang.org/x/crypto/bcrypt" 7 8 "github.com/ShoshinNikita/budget-manager/internal/logger" 9 "github.com/ShoshinNikita/budget-manager/internal/pkg/errors" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/reqid" 11 "github.com/ShoshinNikita/budget-manager/internal/web/utils" 12 ) 13 14 type Credentials interface { 15 Get(username string) (secret string, ok bool) 16 } 17 18 func BasicAuthMiddleware(h http.Handler, creds Credentials, log logger.Logger) http.Handler { 19 errUnauthorized := errors.New("unauthorized") 20 21 checkAuth := func(r *http.Request) bool { 22 username, password, ok := r.BasicAuth() 23 if !ok { 24 return false 25 } 26 hashedPassword, ok := creds.Get(username) 27 if !ok { 28 return false 29 } 30 31 return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) == nil 32 } 33 34 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 35 ctx := r.Context() 36 log := reqid.FromContextToLogger(ctx, log) 37 log = log.WithFields(logger.Fields{"ip": r.RemoteAddr}) 38 39 if !checkAuth(r) { 40 log.Warn("invalid auth request") 41 42 w.Header().Set("WWW-Authenticate", `Basic realm="Budget Manager"`) 43 utils.EncodeError(ctx, w, log, errUnauthorized, http.StatusUnauthorized) 44 return 45 } 46 47 log.Debug("successful auth request") 48 h.ServeHTTP(w, r) 49 }) 50 }