Use the net/http package's BasicAuth helper function to validate credentials and return a 401 Unauthorized response if they fail.
package main
import (
"net/http"
"os"
)
func main() {
username := "admin"
password := "secret"
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
if !ok || u != username || p != password {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.Write([]byte("Hello, authorized user!"))
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
Alternatively, use http.HandlerFunc with http.BasicAuth for a cleaner middleware approach:
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
if !ok || u != "admin" || p != "secret" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
http.Handle("/", authMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Protected content"))
})))
log.Fatal(http.ListenAndServe(":8080", nil))
}
Set environment variables for credentials in production:
export BASIC_AUTH_USER="admin"
export BASIC_AUTH_PASS="secret"
Then read them in your code:
username := os.Getenv("BASIC_AUTH_USER")
password := os.Getenv("BASIC_AUTH_PASS")
This ensures credentials aren't hardcoded in your source code.