今晚简单撸了一个,感觉蛮简洁实用,可以 share 出来
mux_filter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| package utils
import (
"net/http"
"github.com/gorilla/mux"
)
var router *mux.Router
type HttpFunc func(w http.ResponseWriter, r *http.Request) bool
type RouteFilter struct {
filters []HttpFunc
hdlr http.HandlerFunc
}
func NewRouteFilter() *RouteFilter {
return &RouteFilter{}
}
func (f *RouteFilter) AddFilter(h HttpFunc) *RouteFilter {
f.filters = append(f.filters, h)
return f
}
func (f *RouteFilter) Handler(h http.HandlerFunc) *RouteFilter {
f.hdlr = h
return f
}
func (f *RouteFilter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
for _, hdlr := range f.filters {
if !hdlr(w, req) {
return
}
}
f.hdlr(w, req)
}
|
使用方法 (实现一个 Basic Auth 的 Filter):
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| package common
import (
"net/http"
"strings"
)
type AuthFunc func(string, string) bool
func AuthFilterWrapper(authFunc AuthFunc) func(w http.ResponseWriter, r *http.Request) bool {
return func(w http.ResponseWriter, r *http.Request) bool {
_, ok := r.Header["Authorization"]
if !ok {
http.Error(w, "Need Authorization Header", http.StatusBadRequest)
return false
}
auth := strings.SplitN(r.Header["Authorization"][0], " ", 2)
if len(auth) != 2 {
http.Error(w, "Bad Syntax", http.StatusBadRequest)
return false
}
if !authFunc(auth[0], auth[1]) {
http.Error(w, "Authorization Failed", http.StatusUnauthorized)
return false
}
return true
}
}
|
app.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| func UserAuth(method, payload string) bool {
switch method {
case "Basic":
p, _ := base64.StdEncoding.DecodeString(payload)
pair := strings.SplitN(string(p), ":", 2)
if len(pair) != 2 {
return false
}
return true
case "Token":
return true
}
return false
}
func InitHandlers(r *mux.Router) {
s := r.PathPrefix(URL_PREFIX).Subrouter()
s.Handle("/test", utils.NewRouteFilter().
AddFilter(common.AuthFilterWrapper(UserAuth)).
Handler(testHandler))
}
func testHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
}
|