首页 > 解决方案 > Gorilla mux,静态文件服务器的中间件

问题描述

请在下面查看我的代码。如您所见,这是一个具有两个端点的简单服务:

  1. /test <-- 使用中间件保护的基本身份验证
  2. /static <-- 提供 ./static 目录中的所有文件

现在我也在尝试将基本身份验证中间件模式添加到 /static 端点​​,但由于某种原因,我无法弄清楚如何。我无法将*route(r.PathPrefix 的结果)转换为middleware()函数可以理解的内容。(我还创建了一个playground,但由于外部导入,这不起作用)

package main

import (
    "encoding/base64"
    "log"
    "net/http"
    "strings"

    "github.com/gorilla/mux"
)

const (
    username = "test"
    password = "test"
)

func main() {
    r := mux.NewRouter()

    // add normal endpoint
    r.HandleFunc("/test", middleWare(myHandler, basicAuth))

    // add static
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))

    srv := &http.Server{
        Handler: r,
        Addr:    "0.0.0.0:8080",
    }

    log.Print("listening on 0.0.0.0:8080")
    log.Fatal(srv.ListenAndServe())
}

func myHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("yes!"))
    return
}

func middleWare(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
    for _, m := range middleware {
        h = m(h)
    }

    return h
}

func basicAuth(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {

        w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)

        s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
        if len(s) != 2 {
            http.Error(w, "Not authorized", 401)
            return
        }

        b, err := base64.StdEncoding.DecodeString(s[1])
        if err != nil {
            http.Error(w, err.Error(), 401)
            return
        }

        pair := strings.SplitN(string(b), ":", 2)
        if len(pair) != 2 {
            http.Error(w, "Not authorized", 401)
            return
        }

        if pair[0] != username || pair[1] != password {
            http.Error(w, "Not authorized", 401)
            return
        }

        h.ServeHTTP(w, r)
    }
}

标签: gobasic-authenticationmiddlewaremux

解决方案


好吧,原来我使用了一个古老版本的多路复用器,它缺少这个use()功能:)。


推荐阅读