Skip to main content

micro 避免直接访问子应用

好的,我们先总结,然后再详细分解回答如何防止用户在正式发布后直接访问子应用。

总结

为了防止用户在正式发布后直接访问子应用,可以采取以下措施:

  1. 使用反向代理:将所有外部请求通过反向代理服务器(如 Nginx)进行管理,确保子服务只能通过主应用访问。
  2. 内部网络访问:将子服务配置为只在内部网络中可访问,避免外部用户直接访问子服务。
  3. API 网关:使用 API 网关(如 Kong、Traefik)来集中管理和路由请求,并控制访问权限。
  4. 认证和授权:在子服务中添加认证和授权机制,确保只有经过主应用认证的请求才能被处理。

详细分解

1. 使用反向代理

概念:反向代理服务器(如 Nginx)可以将外部请求转发到内部服务,从而隐藏内部服务的真实地址。

实现步骤

  • 配置 Nginx,将所有对子服务的请求转发到主应用。
  • 例如,Nginx 配置文件可以将 /service1/service2 的请求分别转发到 localhost:8081localhost:8082
server {
listen 80;
server_name yourdomain.com;

location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /service1/ {
proxy_pass http://localhost:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /service2/ {
proxy_pass http://localhost:8082/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

2. 内部网络访问

概念:将子服务配置为只能在内部网络中访问,避免外部用户直接访问。

实现步骤

  • 修改子服务的监听地址为 127.0.0.1,确保子服务只能在本地接口上访问。
// 服务1 main.go
package main

import (
"github.com/gin-gonic/gin"
"your_project/service1"
)

func main() {
r := gin.Default()
service1.RegisterRoutes(r)
r.Run("127.0.0.1:8081")
}
// 服务2 main.go
package main

import (
"github.com/gin-gonic/gin"
"your_project/service2"
)

func main() {
r := gin.Default()
service2.RegisterRoutes(r)
r.Run("127.0.0.1:8082")
}

3. API 网关

概念:API 网关可以集中管理和路由请求,并控制访问权限。

实现步骤

  • 使用 API 网关(如 Kong)配置服务和路由,将请求转发到子服务。
  • 例如,通过 Kong 配置服务和路由。
# 添加服务
curl -i -X POST http://localhost:8001/services/ \
--data name=service1 \
--data url=http://localhost:8081

curl -i -X POST http://localhost:8001/services/ \
--data name=service2 \
--data url=http://localhost:8082

# 添加路由
curl -i -X POST http://localhost:8001/services/service1/routes \
--data 'paths[]=/service1'

curl -i -X POST http://localhost:8001/services/service2/routes \
--data 'paths[]=/service2'

4. 认证和授权

概念:在子服务中添加认证和授权机制,确保只有经过主应用认证的请求才能被处理。

实现步骤

  • 在主应用中生成 JWT 令牌,并在子服务中验证该令牌。
// 主应用生成JWT令牌
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user_id",
"exp": time.Now().Add(time.Hour * 72).Unix(),
})

tokenString, err := token.SignedString([]byte("your_secret_key"))
if err != nil {
log.Fatal(err)
}

// 将tokenString发送给客户端
// 子服务验证JWT令牌
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
return
}

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("your_secret_key"), nil
})

if err != nil || !token.Valid {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
return
}

c.Next()
}
}

// 在服务1和服务2的路由中使用中间件
r.Use(AuthMiddleware())

总结

通过使用反向代理、内部网络访问、API 网关和认证授权等多种方法,你可以有效地防止用户直接访问子服务,确保所有请求都通过主应用进行管理和路由。