如何在go中将多个处理程序分配给同一uri?

时间:2018-07-12 17:12:20

标签: http go handler

当请求中出现“ /”模式时,我需要完成两项任务,这两项都需要使用http处理程序。

它们是:

http.Handle("/", http.FileServer(http.Dir("dtfw-tool/build/")))
http.HandleFunc("/", index)

索引处理程序检查访问网页的身份验证是否正确,并且其上方的处理程序提供目录(将来,我将使其进入仅在满足身份验证要求的情况下为目录提供服务的位置)。

是否可以为同一模式设置两个处理程序(当前会产生错误)?如果没有,还有其他方法可以检查身份验证并通过单个处理程序提供目录服务吗?

2 个答案:

答案 0 :(得分:2)

创建一个中间件来对用户进行身份验证,然后将处理程序返回到主Handle,它将包装您的最终处理程序

package main

import (
    "log"
    "net/http"
)

func main() {
    finalHandler := http.HandlerFunc(final)
    http.Handle("/", authentication(finalHandler))
    http.ListenAndServe(":3000", nil)
}

func authentication(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("Executing authentication")
        next.ServeHTTP(w, r) //`next.ServeHTTP(w, r)` will forward the request and response to next handler.
    })
}

func final(w http.ResponseWriter, r *http.Request) {
    log.Println("Executing finalHandler")
    w.Write([]byte("User authenticated"))
}

在Golang HanlderFunc中,用于返回hanlder,它将成为包装主函数的中间件:

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

它也在server.go

的源代码中定义

Playground Example

答案 1 :(得分:1)

我将不得不撤回之前的答案,因为这与我要寻找的东西(必须导入github.com/abbot/go-http-auth)非常接近:

package main

import (
    "fmt"
    "net/http"
    auth "github.com/abbot/go-http-auth"
)

func Secret(user, realm string) string {
    if user == "john" {
        // password is "hello"
        return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
    }
    return ""
}

func main() {
    fmt.Println("-----> Starting HTTP server...")

authenticator := auth.NewBasicAuthenticator("secret.com", Secret)
http.HandleFunc("/", authenticator.Wrap(func(res http.ResponseWriter, req *auth.AuthenticatedRequest) {
    http.FileServer(http.Dir(".")).ServeHTTP(res, &req.Request)
}))

http.ListenAndServe(":5042", nil)
}

这种方法更容易遵循且更具直觉(至少对我而言)。

相关问题