Skip to content

Commit 60329b1

Browse files
committed
feat: add communication with basic permission management module
1 parent 67188dd commit 60329b1

File tree

1 file changed

+61
-10
lines changed

1 file changed

+61
-10
lines changed

go_codes/reverse-proxy.go

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import (
66
"log"
77
"net/http"
88
"net/url"
9+
"time"
910
)
1011

1112
// ReverseProxy 结构体,用于管理反向代理的目标服务器
1213
type ReverseProxy struct {
1314
Targets []*url.URL
1415
Transport http.RoundTripper
1516
current int
17+
//新增部分
18+
AuthCheckClient *http.Client // 权限管理模块的客户端
19+
AuthCheckURL string // 权限管理模块的检查URL
1620
}
1721

1822
// 选择目标服务器,轮询算法
@@ -22,46 +26,93 @@ func (rp *ReverseProxy) getNextTarget() *url.URL {
2226
return target
2327
}
2428

29+
// 创建了一个新的方法checkAuthorization,它会构造一个请求发送给权限管理模块,并根据其响应决定是否继续处理原始请求。
30+
// 如果权限管理模块拒绝了请求或返回非成功的状态码,则返回错误。
31+
// 检查权限
32+
func (rp *ReverseProxy) checkAuthorization(req *http.Request) error {
33+
userID := req.Header.Get("X-User-ID") // 获取用户ID
34+
if userID == "" { //并且如果用户ID缺失,则直接返回错误。这确保了权限管理模块有足够的信息来进行授权决策。
35+
return fmt.Errorf("missing user ID")
36+
}
37+
// 创建一个新的请求发送到权限管理模块
38+
authReq, err := http.NewRequest("POST", rp.AuthCheckURL, nil)
39+
if err != nil {
40+
return fmt.Errorf("failed to create auth request: %v", err)
41+
}
42+
43+
// 将原始请求的相关信息添加到权限管理模块请求的头部或body中,例如用户ID、请求路径等
44+
// 这里假设权限管理模块期望在header中找到这些信息
45+
authReq.Header.Set("X-Original-User", userID) //将用户ID添加到发送给权限管理模块的请求头部,以便权限管理模块可以根据用户信息进行权限检查。//新增部分,方便联动
46+
authReq.Header.Set("X-Original-Path", req.URL.Path)
47+
authReq.Header.Set("X-Original-Method", req.Method)
48+
// 可以根据实际情况添加更多需要传递的信息
49+
50+
// 发送请求到权限管理模块
51+
resp, err := rp.AuthCheckClient.Do(authReq)
52+
if err != nil {
53+
return fmt.Errorf("error contacting auth service: %v", err)
54+
}
55+
defer resp.Body.Close()
56+
57+
// 检查权限管理模块的响应状态码
58+
if resp.StatusCode != http.StatusOK {
59+
body, _ := io.ReadAll(resp.Body) // 读取响应体以便记录更多错误信息
60+
return fmt.Errorf("auth service denied the request with status code: %d, response: %s", resp.StatusCode, string(body)) //在权限检查失败时,不仅检查状态码,还读取权限管理模块的响应体,并将其包含在错误信息中。这有助于更详细地了解权限拒绝的原因,便于调试和问题排查。
61+
}
62+
63+
return nil
64+
}
65+
2566
// ServeHTTP 方法,用于处理请求并将其转发到目标服务器
2667
func (rp *ReverseProxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
27-
// 选择目标服务器
28-
target := rp.getNextTarget()
68+
// 检查权限
69+
if err := rp.checkAuthorization(req); err != nil {
70+
log.Printf("Authorization check failed: %v", err)
71+
http.Error(w, "Forbidden.", http.StatusForbidden)
72+
return
73+
}
2974

30-
// 修改请求的 URL,将请求重定向到目标服务器
75+
// 如果权限检查通过,则继续处理请求
76+
target := rp.getNextTarget()
3177
req.URL.Scheme = target.Scheme
3278
req.URL.Host = target.Host
3379
req.RequestURI = "" // 去掉原始请求的 URI
3480

35-
// 使用指定的 Transport 来发送请求到后端服务器
3681
resp, err := rp.Transport.RoundTrip(req)
3782
if err != nil {
38-
// 错误处理
3983
log.Printf("Error contacting backend %s: %v", target.Host, err)
4084
http.Error(w, fmt.Sprintf("Error contacting backend: %v", err), http.StatusInternalServerError)
4185
return
4286
}
4387
defer resp.Body.Close()
4488

45-
// 将后端服务器的响应复制到客户端
4689
for key, value := range resp.Header {
4790
w.Header()[key] = value
4891
}
4992
w.WriteHeader(resp.StatusCode)
5093
io.Copy(w, resp.Body)
5194
}
5295

53-
// main 函数,设置反向代理并启动 HTTP 服务器
5496
func main() {
5597
// 配置多个后端服务器
5698
targetURLs := []*url.URL{
57-
// 请替换成你实际的目标服务器地址
5899
&url.URL{Scheme: "http", Host: "127.0.0.1:8081"},
59100
}
60101

102+
// 权限管理模块的URL和HTTP客户端配置
103+
//根据github库里面负责权限管理同学写的代码 权限检查的API端点是在http://auth-service:8001/verify
104+
authCheckURL := "http://auth-service:8001/verify" // 更新为权限管理模块的实际地址
105+
authCheckClient := &http.Client{
106+
Timeout: 5 * time.Second, // 设置5秒的超时时间
107+
}
108+
// 创建带有超时设置的HTTP客户端
109+
61110
// 创建一个反向代理实例
62111
proxy := &ReverseProxy{
63-
Targets: targetURLs,
64-
Transport: http.DefaultTransport,
112+
Targets: targetURLs,
113+
Transport: http.DefaultTransport,
114+
AuthCheckClient: authCheckClient,
115+
AuthCheckURL: authCheckURL,
65116
}
66117

67118
// 设置 HTTP 路由,所有请求都交给反向代理处理

0 commit comments

Comments
 (0)