Files
quyun-v2/backend/app/middlewares/super.go

69 lines
1.8 KiB
Go

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()
}