This commit is contained in:
2026-07-15 21:44:13 +08:00
parent 024b6614ba
commit 4794be896c
22 changed files with 1041 additions and 74 deletions

View File

@@ -6,6 +6,9 @@ import (
"time"
"hyapi-server/internal/config"
securityEntities "hyapi-server/internal/domains/security/entities"
securityServices "hyapi-server/internal/domains/security/services"
user_repositories "hyapi-server/internal/domains/user/repositories"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
@@ -14,15 +17,24 @@ import (
// JWTAuthMiddleware JWT认证中间件
type JWTAuthMiddleware struct {
config *config.Config
logger *zap.Logger
config *config.Config
logger *zap.Logger
userRepo user_repositories.UserRepository
blacklist *securityServices.BlacklistService
}
// NewJWTAuthMiddleware 创建JWT认证中间件
func NewJWTAuthMiddleware(cfg *config.Config, logger *zap.Logger) *JWTAuthMiddleware {
func NewJWTAuthMiddleware(
cfg *config.Config,
logger *zap.Logger,
userRepo user_repositories.UserRepository,
blacklist *securityServices.BlacklistService,
) *JWTAuthMiddleware {
return &JWTAuthMiddleware{
config: cfg,
logger: logger,
config: cfg,
logger: logger,
userRepo: userRepo,
blacklist: blacklist,
}
}
@@ -75,6 +87,10 @@ func (m *JWTAuthMiddleware) Handle() gin.HandlerFunc {
return
}
if !m.ensureUserAllowed(c, claims.UserID) {
return
}
// 将用户信息添加到上下文
c.Set("user_id", claims.UserID)
c.Set("username", claims.Username)
@@ -124,6 +140,52 @@ func (m *JWTAuthMiddleware) validateToken(tokenString string) (*JWTClaims, error
return claims, nil
}
// ensureUserAllowed 复查用户是否仍可访问(黑名单即时生效)
func (m *JWTAuthMiddleware) ensureUserAllowed(c *gin.Context, userID string) bool {
if m.userRepo == nil || userID == "" {
return true
}
user, err := m.userRepo.GetByID(c.Request.Context(), userID)
if err != nil {
m.logger.Warn("查询用户状态失败", zap.String("user_id", userID), zap.Error(err))
m.respondUnauthorized(c, "用户状态无效")
return false
}
if user.IsOnBlacklist() {
if m.blacklist != nil {
m.blacklist.RecordHit(&securityEntities.BlacklistHitRecord{
HitType: securityEntities.HitTypeUserJWT,
UserID: userID,
Phone: user.Phone,
IP: c.ClientIP(),
Path: c.Request.URL.Path,
Method: c.Request.Method,
Reason: user.BlacklistReason,
UserAgent: c.GetHeader("User-Agent"),
})
}
m.respondForbidden(c, "账号已被列入黑名单")
return false
}
if !user.CanLogin() {
m.respondForbidden(c, "账号不可用")
return false
}
return true
}
// respondForbidden 禁止访问
func (m *JWTAuthMiddleware) respondForbidden(c *gin.Context, message string) {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": "访问被拒绝",
"error": message,
"request_id": c.GetString("request_id"),
"timestamp": time.Now().Unix(),
})
c.Abort()
}
// respondUnauthorized 返回未授权响应
func (m *JWTAuthMiddleware) respondUnauthorized(c *gin.Context, message string) {
c.JSON(http.StatusUnauthorized, gin.H{
@@ -331,6 +393,10 @@ func (m *AdminAuthMiddleware) Handle() gin.HandlerFunc {
return
}
if !m.jwtAuth.ensureUserAllowed(c, claims.UserID) {
return
}
// 检查用户类型是否为管理员
if claims.UserType != "admin" {
m.respondForbidden(c, "需要管理员权限")