How to control router access permissions in Golang web application

ale_ukr

Oleksandr Ivanchenko

Posted on May 17, 2019

How to control router access permissions in Golang web application

In this post I'm going to describe how can we limit user access to the specific url in golang web application. I will use chi router - a lightweight, idiomatic and composable router for building Go HTTP services.

Let's create our main package.

package main

import (
    "net/http"
    "github.com/go-chi/chi"
)

func main() {
  r := chi.NewRouter()

  r.Get("/", homePageHandler)
  r.Get("/admin", adminPageHandler)
  http.ListenAndServe(":3000", r)
}

func homePageHandler(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("This is home page")) 
}

func adminPageHandler(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("This is admin page")) 
}
Enter fullscreen mode Exit fullscreen mode

After this, if we go to the /admin page, we will see "This is admin page".

Now, let's make this path accessible only for admin.

We have to replace

r.Get("/admin", adminPageHandler)
With
r.Mount("/admin", adminRouter())

Mount attaches another http.Handler or chi Router as a subrouter along a routing path.

Then, we have to attach middleware inside adminRouter() function.

func adminRouter() http.Handler {
    r := chi.NewRouter()
    // Middleware with access rules for router.
    r.Use(AdminOnly)
    r.Get("/", adminPageHandler)

    return r
}
Enter fullscreen mode Exit fullscreen mode

In this middleware we have a simple check is user authorized to access this page or not.

func AdminOnly(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // If user is admin, allows access.
        if IsLoggedInAdmin(r) {
            next.ServeHTTP(w, r)
        } else {
            // Otherwise, 403.
            http.Error(w, http.StatusText(403), 403)
            return
        }

        return
    })
}
Enter fullscreen mode Exit fullscreen mode

In sake of demonstration, I'm going just to use a random bool function to decide is used admin or not. You can modify this function according to your user authentication model.

func IsLoggedInAdmin(r *http.Request) bool {
    return rand.Float32() < 0.5
}
Enter fullscreen mode Exit fullscreen mode

And that's it. Looks really simple, Isn't it?

Let's go to to the /admin page again.

As you see, now, sometimes (depends on our random decider), user has no access to this page anymore.

You can find source code here

💖 💪 🙅 🚩
ale_ukr
Oleksandr Ivanchenko

Posted on May 17, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related