在Go web app路由器中检查用户权限的最佳方法

时间:2018-04-09 10:15:12

标签: go web permissions middleware

我的网络应用包含三种访问级别的网址:

  • 任何人都可以访问的内容(登录页面和静态资产)
  • 登录的可访问的常规用户和管理员
  • 只有登录的管理员才能访问

我应该为路由器中的每个网址格式指定最低访问级别,以便阻止该级别以下的用户。 (我想他们应该得到HTTP错误401或403.)

如何最好地实施这些检查,以便我不必记住将它们分别放在每个URL处理函数中(这很容易忘记)?理想情况下,我想做这样的事情:

router.Get("/someRegularPage", regularAccess(handleSomeRegularPage))
router.Get("/someAdminPage", adminAccess(handleSomeAdminPage))
router.Get("/", publicAccess(handleLoginPage))

是否有一些半标准的中间件可以做到这一点,它是如何工作的?写我自己有多难?

此外,如果我忘记为某些URL指定访问级别,则默认权限是拒绝访问所有人,这将是很好的。编译器警告或错误是理想的。

2 个答案:

答案 0 :(得分:4)

写你自己并不难。假设您将管理令牌存储在名为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方法,不管是因为CORS。

答案 1 :(得分:0)

简短的回答是编写中间件来处理授权。从长远来看,可以帮助您解决问题的更长答案是为您的端点和中间件使用适当的路由路径。例如,您可以使用/api/admin为所有管理路由添加前缀,然后使用相关的admin-auth中间件将路由器包装到各个路由之后。