package transport import ( "strings" "github.com/gin-gonic/gin" "github.com/geo-platform/tenant-api/internal/ops/app" "github.com/geo-platform/tenant-api/internal/shared/middleware" "github.com/geo-platform/tenant-api/internal/shared/response" ) func authMiddleware(issuer *app.TokenIssuer) gin.HandlerFunc { return func(c *gin.Context) { header := c.GetHeader("Authorization") raw, ok := bearerToken(header) if !ok { response.Error(c, response.ErrUnauthorized(40101, "missing_bearer_token", "缺少认证 token")) c.Abort() return } claims, err := issuer.Parse(raw) if err != nil { response.Error(c, response.ErrUnauthorized(40102, "invalid_access_token", "token 无效或已过期")) c.Abort() return } actor := &app.Actor{ OperatorID: claims.OperatorID, Username: claims.Username, DisplayName: claims.DisplayName, Role: claims.Role, IP: c.ClientIP(), UserAgent: c.Request.UserAgent(), RequestID: middleware.RequestIDFromGin(c), } c.Set(actorGinKey, actor) c.Request = c.Request.WithContext(app.WithActor(c.Request.Context(), actor)) c.Next() } } const actorGinKey = "ops_actor" func actorFromGin(c *gin.Context) *app.Actor { if v, ok := c.Get(actorGinKey); ok { if actor, ok := v.(*app.Actor); ok { return actor } } return nil } func bearerToken(header string) (string, bool) { parts := strings.SplitN(header, " ", 2) if len(parts) != 2 || !strings.EqualFold(parts[0], "bearer") { return "", false } token := strings.TrimSpace(parts[1]) return token, token != "" }