后台管理系统嵌入了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 main
import (
"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 = true
gitbook = "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 error
if https {
err = http.ListenAndServeTLS(host, "server.pem", "server.key", nil)
} else {
err = http.ListenAndServe(host, nil)
}
if err != nil {
log.Fatal(err)
}
}
