如何在中间件中获取路由参数?

How to reach route parameters in middleware?

我正在使用 gorilla mux 进行请求路由。 我写了一个基本的中间件,我想将 user 变量添加到上下文中以便在处理程序中访问。但是我找不到如何在中间件中获取路由参数:

router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/{username}/accounts", AccountListHandler)

log.Fatal(http.ListenAndServe(":8080", AuthMiddleware(router)))

中间件代码:

func AuthMiddleware(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // params := mux.Vars(r)
        // fmt.Printf("%v", params["username"])
        user := User{Username: "myUsername"}
        ctx := context.WithValue(r.Context(), "user", user)
        h.ServeHTTP(w, r.WithContext(ctx))
    })
}

我想在中间件中获取 username 参数。我该怎么做?

按照您的设置方式,您将无法访问 username。原因是您的 AuthMiddleware 之前执行 路径参数由 router 提取,因为它包含在您的中间件中(AuthMiddleware(router) ).

您需要使用您的中间件来包装您的处理程序,然后像这样向路由器注册它:

router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/{username}/accounts", AuthMiddleware(AccountListHandler))

log.Fatal(http.ListenAndServe(":8080", router))

如果您有许多处理程序要用中间件包装,而不必重复太多,您可以像这样编写一个简单的循环:

var handlers = map[string]http.HandlerFunc{
    "/{username}/accounts": AccountListHandler,
    // ...
}

router := mux.NewRouter().StrictSlash(true)    
for pattern, handler := range handlers {
    router.HandleFunc(pattern, AuthMiddleware(handler))
}

log.Fatal(http.ListenAndServe(":8080", router))