在 Go 网络应用程序路由器中检查用户权限的最佳方法

Best way to check user permissions in a Go web app router

我的网络应用在三个访问级别上有 URLs:

我应该在我的路由器中为每个 URL 模式指定最低访问级别,以便阻止低于该级别的人。 (我想他们应该得到 HTTP 错误 401 或 403。)

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

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

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

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

自己编写并不难。假设您将管理令牌存储在名为 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)
    }
}

由于 CORS,OPTIONS 方法可能必须被授权。

简短的回答是编写中间件来处理授权。一个更长的答案可能会帮助您解决长 运行 中的问题,那就是为您的端点以及该中间件使用适当的路由路径。例如,您可以为所有管理路由添加 /api/admin 前缀,然后使用相关的 admin-auth 中间件为各个路由包装路由器。