My web app has URLs at three access levels:
I should specify the minimum access level for each URL pattern in my router, so that people below that level are blocked. (I suppose they should get HTTP error 401 or 403.)
How do I best implement these checks so that I don't have to remember to put them in every URL handler function separately (which is very easy to forget)? Ideally I'd like to do something like this:
router.Get("/someRegularPage", regularAccess(handleSomeRegularPage))
router.Get("/someAdminPage", adminAccess(handleSomeAdminPage))
router.Get("/", publicAccess(handleLoginPage))
Is there some semi-standard middleware to do this and how does that work? How hard would it be to write my own?
Additionally, it would be great if the default permission was to deny access to everybody in case I forget to specify the access level for some URL. A compiler warning or error would be ideal.
Writing your own is not hard. Assuming you store your admin token in an environment variable called ADMINTOKEN :
func AdminOnly(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization")
if r.Method == "OPTIONS" {
f(w, r)
return
}
h := r.Header.Get("Authorization")
token := strings.TrimPrefix(h, "Bearer ")
if token == os.Getenv("ADMINTOKEN") {
f(w, r)
return
}
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
}
OPTIONS method may have to be authorized regardless because of CORS.