首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在gorilla mux中的Get子路由器中使用特定路由的特定中间件

如何在gorilla mux中的Get子路由器中使用特定路由的特定中间件
EN

Stack Overflow用户
提问于 2020-11-10 20:28:29
回答 3查看 3.4K关注 0票数 2

我对Gorilla mux路由有一个特定的需求,我想为一个子路由器下的不同路由添加不同的中间件(在我的例子中是GET子路由器)。下面是我的路由代码:

代码语言:javascript
复制
    // 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)

在上面的路由器逻辑中,my /refresh-token和/user-profile令牌都属于getR路由器。我还有两个名为ValidateAccessToken和ValidateRefreshToken的中间件函数。我想对"/refresh-token“路由使用ValidateRefreshToken中间件函数,对GET子路由器下的所有其他路由使用ValidateAccessToken。我想用Gorilla多路复用器路由本身来实现。请向我推荐完成上述方案的适当方法。感谢您的时间和努力。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-11-10 21:45:54

我有一个类似的用例,这是我如何解决它的一个例子:

代码语言:javascript
复制
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函数允许您将多个处理程序链接在一起。我已经演示了两个中间件功能(ValidateRefreshTokenMethodLogger)。中间件基本上是闭包。您可以在任何接受http.Handler的框架(如muxchi )中使用此方法。

票数 2
EN

Stack Overflow用户

发布于 2020-11-11 13:12:47

notorious.no提供的解决方案也可以完美地满足给定的需求。此外,我还遇到了另一个使用PathPrefix的解决方案,它解决了相同的问题,并希望获得相同的建议。

代码语言:javascript
复制
    // 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

票数 5
EN

Stack Overflow用户

发布于 2021-04-28 09:22:37

还有另一个

使用示例

代码语言:javascript
复制
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))

和实施

代码语言:javascript
复制
// 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)
                }
            }
        })
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64768950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档