go - 如何在 gorilla Mux的Get Subrouter中将特定中间件用于特定路由

标签 go routes gorilla

我对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 token 都位于getR路由器下。我也有两个中间件功能,称为ValidateAccessToken和ValidateRefreshToken。我想对“/refresh-token”路由使用ValidateRefreshToken中间件功能,对GET子路由器下的所有其他路由使用ValidateAccessToken。我想用 gorilla 多路复用器路由本身来做到这一点。请为我建议完成上述情况的适当方法。感谢您的时间和精力。

最佳答案

我有一个类似的用例,这是如何解决该问题的一个示例:

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个中间件函数(ValidateRefreshTokenMethodLogger)。中间件基本上是闭包。您可以在接受http.Handler的任何框架(例如muxchi)中使用此方法。

关于go - 如何在 gorilla Mux的Get Subrouter中将特定中间件用于特定路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64768950/

相关文章:

go - 在 go 中使用静态类型构造函数有什么明显的缺点吗?

go - 设置 Martini 日志路径

go - 如何根据请求 URL 使用 golang GIN 路由 HTTP 请求

go - 包 "main"和功能 "main"

javascript - react 重定向/路由器

ruby-on-rails - has_many 嵌套中的自定义 RESTful 路由

javascript - Meteor - 加载/刷新页面时出错 : Exception from Tracker afterFlush function: undefined

球童代理的 WebSocket 握手错误

golang 在指定路径返回静态 html 文件

google-app-engine - 如何在 Google App Engine 标准环境中使用 Gorilla session 避免内存泄漏?