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

huangapple go评论120阅读模式
英文:

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参数。我该如何做到这一点?

英文:

I am using gorilla mux for request routing.
I wrote a basic middleware which I want to add user variable to context for reach in handlers. But I chould not found how can I get route parameter in the middleware:

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

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

Middleware code:

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))
    })
}

I want to reach username paramter in the middleware. How can I do this?

答案1

得分: 2

你设置的方式无法访问username。原因是你的AuthMiddlewarerouter提取路径参数之前执行,因为它被包裹在你的中间件(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))
英文:

The way you have it setup you will not be able to access the username. The reason for that is that your AuthMiddleware is executed before the path parameters are extracted by the router since it is wrapped inside your middleware (AuthMiddleware(router)).

You need use your middleware to wrap your handlers and then register it with the router like so:

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

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

If you have many handlers that you want to wrap with your middleware without having to repeat yourself too much you can write a simple loop like so:

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))

huangapple
  • 本文由 发表于 2017年5月15日 20:22:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/43979440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定