webapi: Implement optional API key to secure the API against unauthenticated attackers.

This commit is contained in:
Kleissner
2021-11-16 19:27:53 +01:00
parent d06c2e0b1a
commit f9d8ecb6b0
3 changed files with 43 additions and 7 deletions

View File

@@ -14,6 +14,7 @@ import (
"time"
"github.com/PeernetOfficial/core"
"github.com/google/uuid"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)
@@ -33,13 +34,18 @@ var WSUpgrader = websocket.Upgrader{
// Start starts the API. ListenAddresses is a list of IP:Ports.
// The certificate file and key are only used if SSL is enabled. The read and write timeout may be 0 for no timeout.
func Start(ListenAddresses []string, UseSSL bool, CertificateFile, CertificateKey string, TimeoutRead, TimeoutWrite time.Duration) {
// The API key may be uuid.Nil to disable it although this is not recommended for security reasons.
func Start(ListenAddresses []string, UseSSL bool, CertificateFile, CertificateKey string, TimeoutRead, TimeoutWrite time.Duration, APIKey uuid.UUID) {
if len(ListenAddresses) == 0 {
return
}
Router = mux.NewRouter()
if APIKey != uuid.Nil {
Router.Use(authenticateMiddleware(APIKey))
}
Router.HandleFunc("/test", apiTest).Methods("GET")
Router.HandleFunc("/status", apiStatus).Methods("GET")
Router.HandleFunc("/account/info", apiAccountInfo).Methods("GET")
@@ -134,3 +140,23 @@ func DecodeJSON(w http.ResponseWriter, r *http.Request, data interface{}) (err e
return nil
}
// authenticateMiddleware returns a middleware function to be used with mux.Router.Use(). It handles all authentication functionality.
func authenticateMiddleware(APIKey uuid.UUID) func(http.Handler) http.Handler {
return (func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
keyID, err := uuid.Parse(r.Header.Get("x-api-key"))
if err != nil { // Invalid key format
w.WriteHeader(http.StatusUnauthorized)
return
}
if keyID != APIKey {
w.WriteHeader(http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
})
}