Q:

Acceso restringido con Golang

Soy nuevo así que pido disculpas de antemano si no se alguna obviedad. 
Estoy interesado en elaborar un panel de Administración o Admin Panel en la ruta /adminpanel, el problema es que nose como restringir que usuarios no puedan acceder a esa dirección. 
Se que se puede usar el paquete HTTP para obtener la Cookies y de ahí, poder autorizar o no al usuario, pero nose si es la mejor practica. 
Gracias! 

A:

Para hacer esto tienes que "interceptar" la petición para aplicar tu lógica, en este caso autenticar, antes de procesarla. 
Esto se hace con un 'middleware'.  La forma más básica es una función con la firma (f http. HandlerFunc) http. HandlerFunc, es decir, una función que toma como parámetro un http. HandlerFunc y devuelve otra función del mismo tipo.  De este modo se pueden encadenar. 
Hay que tener en cuenta que cada framework (Gin, Echo, Chi, etc) suele utilizar su propia definición de middleware, pero también suelen proporcionar wrappers al modelo estándar que indico aquí. 
http. HandlerFunc está definida en la librería estándar, dentro del paquete http y te permite construir un Handler http a partir de una función estándar. 
Por ejemplo, el siguiente middleware
func timeit(next http. HandlerFunc) http. HandlerFunc {
    return func(w http. ResponseWriter, r *http. Request) {
        // se ejecuta antes de llamar al next, el siguiente handler en la cadena. 
        // Aquí es dónde añadirías tu comprobación de autenticación (cookies, JWT,...)
        t := time. Now()
        next(w, r)  // llamamos al siguiente handler (también podemos abortar la ejecución
        // una vez finalizada la ejecución, volvemos a tener el control
        log. Printf("%s se ha ejecutado en %vµs", r.Method, time. Since(t).Nanoseconds())
    }
}

muestra el tiempo de ejecución de la consulta, tomandolo al inicio de la secuencia y al final. 
Para dar un poco de contexto, añado un ejemplo completo:
package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
    "time"
)

func main() {
    http. Handle("/foo", timeit(hello))

    log. Fatal(http. ListenAndServe(":8080", nil))
}

func hello(w http. ResponseWriter, r *http. Request) {
        fmt. Fprintf(w, "Hello, %q", html. EscapeString(r. URL.Path))
}

func timeit(next http. HandlerFunc) http. HandlerFunc {
    return func(w http. ResponseWriter, r *http. Request) {
        // se ejecuta antes de llamar al next, el siguiente handler en la cadena
        t := time. Now()
        next(w, r) // llamamos al siguiente handler (también podemos abortar la ejecución
        // una vez finalizada la ejecución, volvemos a tener el control
        log. Printf("%s se ha ejecutado en %vµs", r.Method, time. Since(t).Microseconds())
    }
}

