Search code examples
authenticationgoservice

How to check authentication for hundreds and thousands of API endpoints?


I am currently building a web application in golang (with Gorilla) and have implemented a handful of API endpoints. However, I noticed that every time I implement a function like:

func CreateUserHandler(w http.ResponseWriter, r *http.Request) {}

I have to add the function below to the body of handler functions to check if request is authorized:

func checkAuthorizedUser (r * http.Request) error {
    uid, err := CheckRequestUser (r.Cookie("uid"))
    if err != nil {
        return errors.New("Can't find cookie value for uid")
    }
    if !IsValidUser (uid.Value) { 
        return errors.New("Not a valid user")
    }
    return nil
}

What happens to me right now is that I have to add checkAuthorizedUser() to every handler function, and I have already have a lot of handler functions so far. I wonder if there is a better way to check whether a client is authorized to access certain endpoint other than explicitly checking authentication in every handler function.


Solution

  • Gorilla has a router you can use. You can then wrap the router with authentication checking. Something like this would work:

    func checkPermissions(h http.Handler) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
            authCheck := true //implement the actual checking
    
            if authCheck {
                w.WriteError(w, 400, "error")
                return
            }
    
            h.ServeHttp(w, r)
        }
    }
    
    func main() {
        r := mux.NewRouter()
        r.HandleFunc("/", HomeHandler)
        r.HandleFunc("/products", ProductsHandler)
        r.HandleFunc("/articles", ArticlesHandler)
        http.Handle("/", checkPermissions(r))
    }
    

    Supporting links:

    https://godoc.org/github.com/gorilla/mux#NewRouter

    https://github.com/gorilla/mux