feat(handler): 实现运维监控 API 处理器和中间件
- 新增 ops 错误日志记录器(ops_error_logger.go) - 新增 ops 主处理器(ops_handler.go) - 新增告警管理处理器(ops_alerts_handler.go) - 新增仪表板处理器(ops_dashboard_handler.go) - 新增实时监控处理器(ops_realtime_handler.go) - 新增配置管理处理器(ops_settings_handler.go) - 新增 WebSocket 处理器(ops_ws_handler.go) - 扩展设置 DTO 支持 ops 配置 - 新增客户端请求 ID 中间件(client_request_id.go) - 新增 WebSocket 查询令牌认证中间件(ws_query_token_auth.go) - 更新管理员认证中间件支持 ops 路由 - 注册 handler 依赖注入
This commit is contained in:
54
backend/internal/server/middleware/ws_query_token_auth.go
Normal file
54
backend/internal/server/middleware/ws_query_token_auth.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// InjectBearerTokenFromQueryForWebSocket copies `?token=` into the Authorization header
|
||||
// for WebSocket handshake requests on a small allow-list of endpoints.
|
||||
//
|
||||
// Why: browsers can't set custom headers on WebSocket handshake, but our admin routes
|
||||
// are protected by header-based auth. This keeps the token support scoped to WS only.
|
||||
func InjectBearerTokenFromQueryForWebSocket() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if c == nil || c.Request == nil {
|
||||
if c != nil {
|
||||
c.Next()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Only GET websocket upgrades.
|
||||
if c.Request.Method != http.MethodGet {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if !strings.EqualFold(strings.TrimSpace(c.GetHeader("Upgrade")), "websocket") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// If caller already supplied auth headers, don't override.
|
||||
if strings.TrimSpace(c.GetHeader("Authorization")) != "" || strings.TrimSpace(c.GetHeader("x-api-key")) != "" {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// Allow-list ops websocket endpoints.
|
||||
path := strings.TrimSpace(c.Request.URL.Path)
|
||||
if !strings.HasPrefix(path, "/api/v1/admin/ops/ws/") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
token := strings.TrimSpace(c.Query("token"))
|
||||
if token != "" {
|
||||
c.Request.Header.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user