修复节点信息API
Some checks failed
build / build (api, amd64, linux) (push) Failing after -46s
build / build (api, arm64, linux) (push) Failing after -51s
build / build (api.exe, amd64, windows) (push) Failing after -51s

This commit is contained in:
CN-JS-HuiBai
2026-04-18 00:52:43 +08:00
parent 64655932b1
commit f9c34fcf87
4 changed files with 123 additions and 5 deletions

View File

@@ -1,17 +1,24 @@
package middleware
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"xboard-go/internal/service"
"github.com/gin-gonic/gin"
)
const nodeAuthPayloadKey = "_node_auth_payload"
func NodeAuth() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Query("token")
nodeID := c.Query("node_id")
nodeType := service.NormalizeServerType(c.Query("node_type"))
token := nodeAuthValue(c, "token")
nodeID := nodeAuthValue(c, "node_id")
nodeType := service.NormalizeServerType(nodeAuthValue(c, "node_type"))
if token == "" || nodeID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"message": "missing node credentials"})
@@ -49,3 +56,98 @@ func NodeAuth() gin.HandlerFunc {
c.Next()
}
}
func nodeAuthValue(c *gin.Context, key string) string {
if value := strings.TrimSpace(c.Query(key)); value != "" {
return value
}
if value := strings.TrimSpace(c.PostForm(key)); value != "" {
return value
}
switch key {
case "token":
if value := strings.TrimSpace(c.GetHeader("X-Server-Token")); value != "" {
return value
}
if auth := strings.TrimSpace(c.GetHeader("Authorization")); len(auth) > 7 && strings.EqualFold(auth[:7], "Bearer ") {
return strings.TrimSpace(auth[7:])
}
case "node_id":
if value := strings.TrimSpace(c.GetHeader("X-Node-Id")); value != "" {
return value
}
case "node_type":
if value := strings.TrimSpace(c.GetHeader("X-Node-Type")); value != "" {
return value
}
}
payload := nodeAuthPayload(c)
if payload == nil {
return ""
}
return nodeAuthString(payload[key])
}
func nodeAuthPayload(c *gin.Context) map[string]any {
if cached, ok := c.Get(nodeAuthPayloadKey); ok {
if payload, ok := cached.(map[string]any); ok {
return payload
}
return nil
}
if c.Request == nil || c.Request.Body == nil {
c.Set(nodeAuthPayloadKey, map[string]any(nil))
return nil
}
contentType := strings.ToLower(c.GetHeader("Content-Type"))
if !strings.Contains(contentType, "application/json") {
c.Set(nodeAuthPayloadKey, map[string]any(nil))
return nil
}
body, err := io.ReadAll(c.Request.Body)
if err != nil {
c.Request.Body = io.NopCloser(bytes.NewBuffer(nil))
c.Set(nodeAuthPayloadKey, map[string]any(nil))
return nil
}
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
if len(bytes.TrimSpace(body)) == 0 {
c.Set(nodeAuthPayloadKey, map[string]any(nil))
return nil
}
var payload map[string]any
if err := json.Unmarshal(body, &payload); err != nil {
c.Set(nodeAuthPayloadKey, map[string]any(nil))
return nil
}
c.Set(nodeAuthPayloadKey, payload)
return payload
}
func nodeAuthString(value any) string {
switch typed := value.(type) {
case string:
return strings.TrimSpace(typed)
case json.Number:
return strings.TrimSpace(typed.String())
default:
if value == nil {
return ""
}
text := strings.TrimSpace(fmt.Sprint(value))
if text == "<nil>" {
return ""
}
return text
}
}