9.6 http中间件

package main

import (
	"io"
	"log"
	"net/http"
)

type User string

func (u User) toString() string {
	return string(u)
}

type AuthHandler func(u User, w http.ResponseWriter, r *http.Request)

func main() {

	// Secured API
	mux := http.NewServeMux()
	mux.HandleFunc("/api/users", Secure(func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, `[{"id":"1","login":"ffghi"},{"id":"2","login":"ffghj"}]`)
	}))
	mux.HandleFunc("/api/profile", WithUser(func(u User, w http.ResponseWriter, r *http.Request) {
		log.Println(u.toString())
		io.WriteString(w, "{\"user\":\""+u.toString()+"\"}")
	}))

	http.ListenAndServe(":8080", mux)

}

func WithUser(h AuthHandler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		user := r.Header.Get("X-User")
		if len(user) == 0 {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}
		h(User(user), w, r)
	}

}

func Secure(h http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		sec := r.Header.Get("X-Auth")
		if sec != "authenticated" {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}
		h(w, r) // use the handler
	}

}

/*
(sx3.5.3) ➜  ~ curl -X GET -I http://127.0.0.1:8080/api/users
HTTP/1.1 401 Unauthorized
Date: Mon, 26 Mar 2018 15:42:50 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8



curl -X GET -w "\nStatus: %{http_code}\n"  http://127.0.0.1:8080/api/users
Status: 401


curl -X GET -w "\nStatus: %{http_code}\n"  http://127.0.0.1:8080/api/users  -H "X-Auth: authenticated"
[{"id":"1","login":"ffghi"},{"id":"2","login":"ffghj"}]
Status: 200

(sx3.5.3) ➜  ~ curl -X GET -w "\nStatus: %{http_code}\n"  http://127.0.0.1:8080/api/profile  -H "X-User: zrd"
{"user":"zrd"}
Status: 200
*/


在前面的例子中中间件的实现利用函数为一等公民的Golang特色。原handlerfunc包装成一个handlerfunc检查x-auth头。安全功能是用来保护handlerfunc,用于servemux的handlefunc方法。

请注意,这只是一个简单的示例,但这种方式可以实现更复杂的解决方案。例如,用户的身份可以从标题标记和随后的提取,处理新类型可以定义为类AuthHandler func(U *用户,W http.responsewriter,R * HTTP请求)。功能的用户创建的servemux的handlerfunc。

posted on 2018-03-26 23:52  cucy_to  阅读(170)  评论(0编辑  收藏  举报

导航