Skip to content

Feature/user#124

Merged
DevVoyagerNext merged 4 commits intomainfrom
feature/user
Mar 25, 2026
Merged

Feature/user#124
DevVoyagerNext merged 4 commits intomainfrom
feature/user

Conversation

@DevVoyagerNext
Copy link
Copy Markdown
Collaborator

@DevVoyagerNext DevVoyagerNext commented Mar 25, 2026

对发送邮箱验证码的频率限制进行了重构。
对邮箱标题和内容进行了重构,防止被qq邮箱官方封号。

Summary by CodeRabbit

发布说明

  • 新功能

    • 扩展邮箱域名支持范围:现已兼容QQ及其关联邮箱服务。
    • 邮件样式优化:采用HTML格式排版,验证码在邮件主题中清晰展示。
  • 缺陷修复

    • 增强邮件发送速率限制机制,改善并发场景处理能力。

@DevVoyagerNext DevVoyagerNext merged commit 4c534c8 into main Mar 25, 2026
3 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3257f105-b7dd-4847-99fb-d13fcb92988f

📥 Commits

Reviewing files that changed from the base of the PR and between 30a8ee4 and 1f59bd5.

📒 Files selected for processing (3)
  • app/user/rpc/internal/logic/qqemail/send_q_q_email_logic.go
  • common/utils/email/email.go
  • common/utils/validate/validator.go

📝 Walkthrough

总体流程

此次 PR 将 QQ 邮件发送的 Redis 速率限制从单一 1 小时计数器重构为多时间窗口方案,引入 60 秒原子锁保证并发安全,同时将邮件格式升级为 HTML,并扩展邮箱域名验证范围。

变更清单

内聚组 / 文件 变更摘要
速率限制重构
app/user/rpc/internal/logic/qqemail/send_q_q_email_logic.go
多时间窗口限流方案:60 秒并发锁(SetNX 原子操作)、1 小时计数器上限 5、24 小时计数器上限 10。锁获取失败返回验证码限流错误。计数器增量延迟到邮件发送成功后。新增 Redis 错误处理路径,包括 redis.Nil 特殊处理。
邮件格式升级
common/utils/email/email.go
Content-Type 从 text/plain 改为 text/html,Subject 追加验证码后缀,邮件正文改用 HTML 模板突出验证码,新增隐藏 div 容纳时间戳。
邮箱域名扩展
common/utils/validate/validator.go
QQ 邮箱正则从仅支持 @qq.com 扩展至 @(qq.com|vip.qq.com|foxmail.com),用户名规则保持不变。

序列图

sequenceDiagram
    participant C as 客户端
    participant S as 邮件服务
    participant R as Redis
    
    C->>S: 发送邮件请求
    S->>R: SetNX rate_limit_60s (TTL=60s)
    alt 锁获取失败
        R-->>S: false (已存在)
        S-->>C: ❌ 验证码限流错误
    else 锁获取成功
        R-->>S: true
        S->>R: Get rate_limit_1h
        R-->>S: counter_1h
        alt 1小时计数 >= 5
            S-->>C: ❌ 小时限流错误
        else
            S->>R: Get rate_limit_24h
            R-->>S: counter_24h
            alt 24小时计数 >= 10
                S-->>C: ❌ 日限流错误
            else
                S->>S: 发送邮件
                alt 发送成功
                    S->>R: INCR rate_limit_1h
                    S->>R: INCR rate_limit_24h
                    S->>R: Set captcha_code
                    S-->>C: ✅ 成功
                else 发送失败
                    S->>R: DEL rate_limit_60s
                    S-->>C: ❌ 邮件发送失败
                end
            end
        end
    end
Loading

代码审查要点

✅ 好的实现

  1. 并发安全性加强 - 用 SetNX 实现原子锁,60 秒窗口有效避免短时间内重复发送,思路清晰
  2. 分层限流设计 - 三层限制(并发、小时、天级)递进式防护,逻辑递进合理
  3. 错误恢复机制 - 邮件发送失败时主动删除锁,防止死锁,细节考虑周全

⚠️ 需要关注的地方

  1. Redis 错误处理的完整性

    • 新增的 Get 操作需检查是否完整处理了 redis.Nil 和网络错误
    • SetNX 锁失败时的区分:是真的冲突还是 Redis 故障?建议添加区分处理
  2. 计数器增量延迟的副作用

    • 邮件发送成功后才 INCR,若此时 Redis 写入失败,计数器不准确
    • 考虑是否需要重试机制或降级策略
  3. 时间窗口的准确性

    • Redis 键的 TTL 失效依赖 Redis 过期机制,若 Redis 未清理过期键会造成计数不准
    • 建议补充监控键过期是否及时
  4. HTML 邮件格式的兼容性

    • 隐藏 div 中的时间戳用途是什么?(追踪?防重放?)建议补充注释
    • HTML 模板中需检查内容注入风险(如验证码本身是否经过转义)
  5. 邮箱正则的测试覆盖

    • 扩展到三个域名后,建议补充单测验证各域名的边界情况(如 test@vip.qq.com.fake.com

🎯 4 (复杂) | ⏱️ ~45 分钟

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/user

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant