golang 反向代理,支持 token 鉴权

go-proxy-pass.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
 
import (
    "flag"
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
    "os"
    "strconv"
    "strings"
    "time"
)
 
const (
    timeFormat = "2006/01/02 15:04:05"
)
 
// 获取当前时间
func NowTimeStr() string {
    return time.Now().Format(timeFormat)
}
 
// NewProxy 拿到 targetHost 后,创建一个反向代理
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
    url, err := url.Parse(targetHost)
    if err != nil {
        return nil, err
    }
 
    return httputil.NewSingleHostReverseProxy(url), nil
}
 
// ProxyRequestHandler 使用 proxy 处理请求
func ProxyRequestHandler(proxy *httputil.ReverseProxy, token string) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        if (token == "" || token == r.Header.Get("token")) {
            proxy.ServeHTTP(w, r)
        } else {
            w.WriteHeader(403)
            w.Header().Set("Content-Type","application/json")
            w.Write([]byte(`{"code":403,"msg":"ERROR 请求头token不合法,或为空"}` + "\n"))
            fmt.Println(NowTimeStr() + " ERROR 请求头token不合法,或为空")
        }
         
    }
}
 
func main() {
    port := flag.Int("port", -1, "服务端口")
    proxy_pass := flag.String("proxy_pass", "", "反向代理地址")
    token := flag.String("token", "", "鉴权token")
    flag.Parse()
 
    if (*port >= 1025 && *port <= 65535) {
        fmt.Println(NowTimeStr() + " INFO 端口号【port】: " + strconv.Itoa(*port))
    } else {
        fmt.Println(NowTimeStr() + " ERROR 端口号【port】取值范围:[ 1025 - 65535 ]")
        os.Exit(1)
    }
 
    if (strings.HasPrefix(*proxy_pass, "http://") || strings.HasPrefix(*proxy_pass, "https://")) {
        fmt.Println(NowTimeStr() + " INFO 反向代理地址【proxy_pass】: " + *proxy_pass)
    } else {
        fmt.Println(NowTimeStr() + " ERROR 反向代理地址【proxy_pass】不合法")
        os.Exit(1)
    }
 
    if (*token != "") {
        fmt.Println(NowTimeStr() + " INFO 鉴权token【token】: " + *token)
    }
 
    // 初始化反向代理并传入真正后端服务的地址
    proxy, err := NewProxy(*proxy_pass)
    if err != nil {
        panic(err)
    }
 
    // 使用 proxy 处理所有请求到你的服务
    http.HandleFunc("/", ProxyRequestHandler(proxy, *token))
    log.Fatal(http.ListenAndServe(":" + strconv.Itoa(*port), nil))
}

 

程序编译:

go build -ldflags "-s -w" go-proxy-pass.go

进一步压缩(可选,需安装upx:https://github.com/upx/upx):

upx -9 go-proxy-pass

 

使用场景:

给 docker REST API 端口添加一层反向代理开启token认证,不想安装 nginx、caddy 等web服务器,只想单文件运行

daemon.json 配置参考:

{
    "hosts":[
        "tcp://127.0.0.1:2375"
    ]
}

  

使用示例:

./go-proxy-pass -port 8375 -proxy_pass http://127.0.0.1:2375

验证:

curl http://127.0.0.1:8375/info

 

使用示例:

./go-proxy-pass -port 8375 -proxy_pass http://127.0.0.1:2375 -token abcdefghijklmnop

验证:

curl -H "token:abcdefghijklmnop" http://127.0.0.1:8375/info

 

posted @   Nihaorz  阅读(181)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示