feat(auth): upgrade casbin to v3 and enhance connection pool configurations
- Upgrade casbin from v2 to v3 across go.mod and pkg/auth/casbin.go - Add slide captcha verification to registration flow (CheckVerified, ConsumeVerified) - Add DB wrapper with connection pool statistics and health checks - Add Redis connection pool optimizations with stats and health monitoring - Add new config options: ConnMaxLifetime, HealthCheckInterval, EnableRetryOnError - Optimize slow query threshold from 200ms to 100ms - Add ping with retry mechanism for database and Redis connections
This commit is contained in:
@@ -180,12 +180,50 @@ func (s *captchaService) Verify(ctx context.Context, dx int, captchaID string) (
|
||||
ty := redisData.Ty
|
||||
ok := slide.Validate(dx, ty, tx, ty, paddingValue)
|
||||
|
||||
// 验证后立即删除Redis记录(防止重复使用)
|
||||
// 验证成功后,标记为已验证状态,设置5分钟有效期
|
||||
if ok {
|
||||
verifiedKey := redisKeyPrefix + "verified:" + captchaID
|
||||
if err := s.redis.Set(ctx, verifiedKey, "1", 5*time.Minute); err != nil {
|
||||
s.logger.Warn("设置验证码已验证标记失败", zap.Error(err))
|
||||
}
|
||||
// 删除原始验证码记录(防止重复验证)
|
||||
if err := s.redis.Del(ctx, redisKey); err != nil {
|
||||
// 记录警告但不影响验证结果
|
||||
s.logger.Warn("删除验证码Redis记录失败", zap.Error(err))
|
||||
}
|
||||
}
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// CheckVerified 检查验证码是否已验证(仅检查captcha_id)
|
||||
func (s *captchaService) CheckVerified(ctx context.Context, captchaID string) (bool, error) {
|
||||
// 测试环境下直接通过验证
|
||||
cfg, err := config.GetConfig()
|
||||
if err == nil && cfg.IsTestEnvironment() {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
verifiedKey := redisKeyPrefix + "verified:" + captchaID
|
||||
exists, err := s.redis.Exists(ctx, verifiedKey)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("检查验证状态失败: %w", err)
|
||||
}
|
||||
if exists == 0 {
|
||||
return false, errors.New("验证码未验证或已过期")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// ConsumeVerified 消耗已验证的验证码(注册成功后调用)
|
||||
func (s *captchaService) ConsumeVerified(ctx context.Context, captchaID string) error {
|
||||
// 测试环境下直接返回成功
|
||||
cfg, err := config.GetConfig()
|
||||
if err == nil && cfg.IsTestEnvironment() {
|
||||
return nil
|
||||
}
|
||||
|
||||
verifiedKey := redisKeyPrefix + "verified:" + captchaID
|
||||
if err := s.redis.Del(ctx, verifiedKey); err != nil {
|
||||
s.logger.Warn("删除验证码已验证标记失败", zap.Error(err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ type VerificationService interface {
|
||||
type CaptchaService interface {
|
||||
Generate(ctx context.Context) (masterImg, tileImg, captchaID string, y int, err error)
|
||||
Verify(ctx context.Context, dx int, captchaID string) (bool, error)
|
||||
CheckVerified(ctx context.Context, captchaID string) (bool, error)
|
||||
ConsumeVerified(ctx context.Context, captchaID string) error
|
||||
}
|
||||
|
||||
// YggdrasilService Yggdrasil服务接口
|
||||
|
||||
@@ -330,10 +330,10 @@ func (s *textureService) UploadTexture(ctx context.Context, uploaderID int64, na
|
||||
}
|
||||
|
||||
// 生成对象名称(路径)
|
||||
// 格式: hash/{hash[:2]}/{hash[2:4]}/{hash}.png
|
||||
// 使用哈希值作为路径,避免重复存储相同文件
|
||||
// 格式: type/hash[:2]/hash
|
||||
// 使用哈希值作为文件名,不带扩展名
|
||||
textureTypeFolder := strings.ToLower(textureType)
|
||||
objectName := fmt.Sprintf("%s/%s/%s/%s/%s%s", textureTypeFolder, hash[:2], hash[2:4], hash, hash, ext)
|
||||
objectName := fmt.Sprintf("%s/%s", textureTypeFolder, hash)
|
||||
|
||||
// 上传文件
|
||||
reader := bytes.NewReader(fileData)
|
||||
|
||||
Reference in New Issue
Block a user