了我直接寫成了嵌套的中間件
並且在第一層實現了 basic auth 的功能.
可能代碼中間有些變量名 沒有很規範
package main
import (
"fmt"
"net/http"
)
// 認證的用戶列表,存儲用戶名以及密碼
var (
list = map[string]string{
"jack":"cat",
}
)
// 第一層中間件的結構體, 他需要實現http.Handler接口
type newhand struct {
hand http.Handler
}
// 第二層 中間價的基礎結構體, 我用它來添加一個 header caonima:woaini
type hand2 struct {
handler http.Handler
}
func (hd *hand2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println("The internal middle")
w.Header().Add("wocaonima","woaini")
hd.handler.ServeHTTP(w,r)
}
func (n *newhand) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Println("Start")
// basic auth ---------------------------------
username, password, ok := r.BasicAuth()
if !ok {
unauthenticate(w,"Not auth")
return
}
realPass, ok := list[username]
if !ok {
unauthenticate(w, "NO PASS")
return
}
if realPass == password {
n.hand.ServeHTTP(w,r)
}
unauthenticate(w,"not right")
// --------------------------------------------
fmt.Println("end")
}
func unauthenticate(w http.ResponseWriter, realm string) {
w.Header().Add("WWW-Authenticate",fmt.Sprintf("Basic realm=%s",realm))
w.WriteHeader(http.StatusUnauthorized)
}
func newhandddd(handler http.Handler) *hand2 {
return &hand2{handler:handler}
}
func newwhandd(handler http.Handler) *newhand {
return &newhand{hand:handler}
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(writer http.ResponseWriter, r *http.Request) {
_, _ = writer.Write([]byte("wocaonima"))
})
//todo dwadwadawd
nn := newwhandd(newhandddd(mux))
err := http.ListenAndServe(":90",nn)
if err != nil {
fmt.Println(err)
return
}
}