后台管理系统嵌入了Gitbook做帮助中心,需要给Gitbook添加下认证。
思路如下:修改Gitbook发布时的js,给每个URL拼接上用户登录后的Token,Gitbook前面有个代理获取这个Token,Token验证成功,则将请求发送给Gitbook server,否则返回403.
本打算用NGINX来实现,但是发现会比较麻烦,不好处理,直接使用go实现下,简单方便。
核心如下:
func Handler(w http.ResponseWriter, r *http.Request) {url, err := url.Parse(gitbook) // gitbook为后端Gitbook server地址if err != nil {log.Fatal(err)}proxy := httputil.NewSingleHostReverseProxy(url)proxy.ServeHTTP(w, r)}
增加个拦截器:
func HTTPInterceptor(h http.HandlerFunc) http.HandlerFunc {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {r.ParseForm()token := r.Form.Get("token")if token == "" || token != token {w.WriteHeader(http.StatusInternalServerError)fmt.Fprintln(w, "403 Forbidden")return}h(w, r)})}
HTTPS的配置
http.ListenAndServeTLS(host, "server.pem", "server.key", nil)
完整代码如下:
package mainimport ("fmt""log""net/http""net/http/httputil""net/url")func init() {log.SetFlags(log.LstdFlags | log.Lshortfile)}// 配置文件var (host = ":8080"token = "a3du27" // 可以从Redis或MySQL中获取然后验证https = truegitbook = "127.0.0.1:7000")func HTTPInterceptor(h http.HandlerFunc) http.HandlerFunc {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {r.ParseForm()token := r.Form.Get("token")if token == "" || token != token {w.WriteHeader(http.StatusInternalServerError)fmt.Fprintln(w, "403 Forbidden")return}h(w, r)})}func Handler(w http.ResponseWriter, r *http.Request) {url, err := url.Parse(gitbook)if err != nil {log.Fatal(err)}proxy := httputil.NewSingleHostReverseProxy(url)proxy.ServeHTTP(w, r)}func main() {http.HandleFunc("/", HTTPInterceptor(Handler))var err errorif https {err = http.ListenAndServeTLS(host, "server.pem", "server.key", nil)} else {err = http.ListenAndServe(host, nil)}if err != nil {log.Fatal(err)}}