如何解决如何在大猩猩Mux的Get Subrouter中将特定中间件用于特定路由
我对Gorilla mux路由有一个特殊的要求,我想为一个子路由器(在我的情况下为GET子路由器)下的不同路由添加不同的中间件。下面是我的路由代码:
// create a serve mux
sm := mux.NewRouter()
// register handlers
postR := sm.Methods(http.MethodPost).Subrouter()
postR.HandleFunc("/signup",uh.Signup)
postR.HandleFunc("/login",uh.Login)
postR.Use(uh.MiddlewareValidateUser)
getR := sm.Methods(http.MethodGet).Subrouter()
getR.HandleFunc("/refresh-token",uh.RefreshToken)
getR.HandleFunc("/user-profile",uh.GetUserProfile)
在上述路由器逻辑中,我的/ refresh-token和/ user-profile令牌都位于getR路由器下。我也有两个中间件功能,称为ValidateAccessToken和ValidateRefreshToken。我想对“ / refresh-token”路由使用ValidateRefreshToken中间件功能,对GET子路由器下的所有其他路由使用ValidateAccessToken。我想用大猩猩多路复用器路由本身来做到这一点。请为我建议完成上述情况的适当方法。感谢您的时间和精力。
解决方法
我有一个类似的用例,这是我如何解决它的一个示例:
package main
import (
"log"
"net/http"
"time"
)
import (
"github.com/gorilla/mux"
)
// Adapter is an alias so I dont have to type so much.
type Adapter func(http.Handler) http.Handler
// Adapt takes Handler funcs and chains them to the main handler.
func Adapt(handler http.Handler,adapters ...Adapter) http.Handler {
// The loop is reversed so the adapters/middleware gets executed in the same
// order as provided in the array.
for i := len(adapters); i > 0; i-- {
handler = adapters[i-1](handler)
}
return handler
}
// RefreshToken is the main handler.
func RefreshToken(res http.ResponseWriter,req *http.Request) {
res.Write([]byte("hello world"))
}
// ValidateRefreshToken is the middleware.
func ValidateRefreshToken(hKey string) Adapter {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter,req *http.Request) {
// Check if a header key exists and has a value
if value := req.Header.Get(hKey); value == "" {
res.WriteHeader(http.StatusForbidden)
res.Write([]byte("invalid request token"))
return
}
// Serve the next handler
next.ServeHTTP(res,req)
})
}
}
// MethodLogger logs the method of the request.
func MethodLogger() Adapter {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter,req *http.Request) {
log.Printf("method=%s uri=%s\n",req.Method,req.RequestURI)
next.ServeHTTP(res,req)
})
}
}
func main() {
sm := mux.NewRouter()
getR := sm.Methods(http.MethodGet).Subrouter()
getR.HandleFunc("/refresh-token",Adapt(
http.HandlerFunc(RefreshToken),MethodLogger(),ValidateRefreshToken("Vikee-Request-Token"),).ServeHTTP)
srv := &http.Server{
Handler: sm,Addr: "localhost:8888",WriteTimeout: 30 * time.Second,ReadTimeout: 30 * time.Second,}
log.Fatalln(srv.ListenAndServe())
}
通过Adapt
函数,您可以将多个处理程序链接在一起。我已经演示了2个中间件函数(ValidateRefreshToken
和MethodLogger
)。中间件基本上是闭包。您可以在接受http.Handler
和mux
之类的接受chi
的框架中使用此方法。
notorious.no提供的解决方案也可以完美地满足给定的要求。另外,我遇到了另一种使用PathPrefix的解决方案,它可以解决相同的问题,并希望获得相同的建议。
// create a serve mux
sm := mux.NewRouter()
// register handlers
postR := sm.Methods(http.MethodPost).Subrouter()
postR.HandleFunc("/signup",uh.Signup)
postR.HandleFunc("/login",uh.Login)
postR.Use(uh.MiddlewareValidateUser)
refToken := sm.PathPrefix("/refresh-token").Subrouter()
refToken.HandleFunc("",uh.RefreshToken)
refToken.Use(uh.MiddlewareValidateRefreshToken)
getR := sm.Methods(http.MethodGet).Subrouter()
getR.HandleFunc("/greet",uh.Greet)
getR.Use(uh.MiddlewareValidateAccessToken)
使用参考:https://github.com/gorilla/mux/issues/360
,还有一个
使用示例
mux := mux.NewRouter()
healthRoute := mux.Path("/health").Handler(healthHandler)
mux.PathPrefix("/").Handler(defaultHandler)
// Run logging middleware except on the health route because health is spammy
mux.Use(libHttp.MiddlewareExcept(libHttp.LoggingMiddlewareWith404(logger),healthRoute))
并实现
// MiddlewareExcept returns a new middleware that calls the provided middleware except on the provided routes
func MiddlewareExcept(middleware mux.MiddlewareFunc,routes ...*mux.Route) mux.MiddlewareFunc {
routeMatch := mux.RouteMatch{}
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter,r *http.Request) {
for _,route := range routes {
if route.Match(r,&routeMatch) {
if next != nil {
next.ServeHTTP(rw,r)
}
} else {
middleware(next).ServeHTTP(rw,r)
}
}
})
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。