package middlewares import ( "strings" "quyun/v2/app/errorx" "quyun/v2/app/services" "quyun/v2/pkg/consts" "quyun/v2/providers/jwt" "github.com/gofiber/fiber/v3" ) func shouldSkipSuperJWTAuth(path string) bool { // 登录接口允许匿名访问。 return strings.Contains(path, "/super/v1/auth/login") } // SuperAuth 平台侧超级管理员鉴权: // - 校验 JWT 并写入 claims // - 加载用户并校验包含 super_admin 角色 func (f *Middlewares) SuperAuth(c fiber.Ctx) error { if shouldSkipSuperJWTAuth(c.Path()) { f.log.Debug("middlewares.super.auth.skipped") return c.Next() } authHeader := c.Get(jwt.HttpHeader) if authHeader == "" { f.log.Info("middlewares.super.auth.missing_token") return errorx.ErrTokenMissing } claims, err := f.jwt.Parse(authHeader) if err != nil { f.log.WithError(err).Warn("middlewares.super.auth.invalid_token") switch err { case jwt.TokenExpired: return errorx.ErrTokenExpired case jwt.TokenMalformed, jwt.TokenNotValidYet, jwt.TokenInvalid: return errorx.ErrTokenInvalid default: return errorx.ErrTokenInvalid } } if claims.UserID == 0 { f.log.Warn("middlewares.super.auth.missing_user_id") return errorx.ErrTokenInvalid } userModel, err := services.User.FindByID(c, claims.UserID) if err != nil { f.log.WithField("user_id", claims.UserID).WithError(err).Warn("middlewares.super.auth.load_user_failed") return err } if !userModel.Roles.Contains(consts.RoleSuperAdmin) { f.log.WithField("user_id", claims.UserID).Warn("middlewares.super.auth.denied") return errorx.ErrPermissionDenied.WithMsg("需要超级管理员权限") } f.log.WithFields(map[string]any{ "user_id": claims.UserID, }).Info("middlewares.super.auth.ok") c.Locals(consts.CtxKeyClaims, claims) c.Locals(consts.CtxKeyUser, userModel) return c.Next() }