为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不使用 DefaultServeMux 的情况下实现 HandlerFunc

如何在不使用 DefaultServeMux 的情况下实现 HandlerFunc

Go
守着星空守着你 2021-11-01 17:19:37
如果我要使用 DefaultServeMux(我通过将它nil作为第二个参数传递给 ListenAndServe 来指定它),那么我可以访问http.HandleFunc,您在下面的 Go wiki 示例中看到了它:func handler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])}func main() {    http.HandleFunc("/", handler)    http.ListenAndServe(":8080", nil)}在我当前的代码中,我无法使用 DefaultServeMux,即我将自定义处理程序传递给 ListenAndServe    h := &mypackage.Handler{        Database: mydb    }    http.ListenAndServe(":8080", h)所以我没有http.HandleFunc内置。但是,我必须将一些授权代码调整到我的代码库中,这些代码需要类似http.HandleFunc. 例如,如果我一直在使用 DefaultServeMux,当我点击"/protected"路由时,我会想去Protected处理程序,但只有在通过h.AuthorizationHandlerFunc这样的   h.AuthorizationHandlerFunc(Protected)但是,由于我没有使用 DefaultServeMux,因此它不起作用,即我无法将Protected函数(并调用它)传递给AuthorizationHandlerFunc. 这是下面 AuthorizationHandlerFunc 的实现。你可以在下面看到Protected永远不会被调用的。问题:HandlerFunc在这种情况下如何实现(不使用 DefaultServeMux)?func (h *Handler) AuthorizationHandlerFunc(next http.HandlerFunc) http.Handler{     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){         h.AuthorizationMiddleWare(w, r, next)   })}func (h *Handler) AuthorizationMiddleWare(w http.ResponseWriter, r *http.Request, next http.HandlerFunc){     //other stuff happens     log.Println("this is never getting called")     next(w,r)}func (h *Handler)Protected(w http.ResponseWriter, r *http.Request){      log.Println("this is never getting called")}更新 ServeHTTP 在 mypackage.Handler 上实现。为什么 Protected 函数没有被调用,或者,AuthorizationMiddleWare 中的相关代码没有被调用?
查看完整描述

1 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

将您的授权中间件重新实现为http.Handler:


type auth struct {

   DB *sql.DB

   UnauthorizedHandler http.Handler

}


func NewAuth(db *sql.DB, unauthorized http.Handler) *auth {

    return auth{db, unauthorized}

}


func (a *auth) Protected(h http.Handler) http.Handler {

    fn := func(w http.ResponseWriter, r *http.Request) {

        // Check whether the request is valid

        // If it's invalid, call your error func and make sure to *return* early!

        if !valid {

            a.UnauthorizedHandler.ServeHTTP(w, r)

            return

        }

        // Call the next handler on success

        h.ServeHTTP(w, r)

        return

    }


    return http.HandlerFunc(fn)

}


func someHandler(w http.ResponseWriter, r *http.Request) {

    io.WriteString(w, "Hello!\n")

}


func main() {

    auth := NewAuth(db, errorHandler)

    r := http.NewServeMux()

    // We have a http.Handler implementation that wraps a http.HandlerFunc

    // ... so we call r.Handle on our ServeMux and type-cast the wrapped func

    r.Handle("/protected", auth.Protected(http.HandlerFunc(someHandler)))

    // Just a simple http.HandlerFunc here

    r.HandleFunc("/public", someOtherHandler)


    log.Fatal(http.ListenAndServe(":8000", r))

}

看看我为一个不同的例子编写的httpauth libServeHTTP方法。以上和ServeHTTP在您的类型上显式创建方法都是有效的方法。


查看完整回答
反对 回复 2021-11-01
  • 1 回答
  • 0 关注
  • 158 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信