跳转至

黑白名单功能

最后更新: 2026-08-04

概述

黑白名单功能允许管理员控制哪些用户可以访问机器人。支持两种模式:

  • 黑名单模式: 禁止特定用户访问(默认允许所有用户)
  • 白名单模式: 只允许特定用户访问(默认禁止所有用户)
  • 禁用模式: 不进行访问控制(默认)

核心特性

✅ 三种模式

  1. 禁用模式 (Disabled)
  2. 不进行任何访问控制
  3. 所有用户都可以访问
  4. 适合公开服务

  5. 黑名单模式 (Blacklist)

  6. 只禁止列表中的用户
  7. 其他所有用户都可以访问
  8. 适合封禁违规用户

  9. 白名单模式 (Whitelist)

  10. 只允许列表中的用户
  11. 其他所有用户都被禁止
  12. 适合内测、私有服务

✅ 管理功能

  • 添加用户: 支持添加备注/原因
  • 移除用户: 从列表中移除
  • 列出用户: 查看所有列表用户
  • 清空列表: 一键清空
  • 统计信息: 查看模式和用户数

✅ 安全特性

  • 并发安全: 使用读写锁保护
  • 备注支持: 记录添加原因
  • 灵活切换: 随时切换模式
  • 中间件集成: 自动检查访问权限

使用指南

命令列表

1. 设置模式

/acl mode <模式>

可用模式: - disabled / disable / off - 禁用 - blacklist / black / bl - 黑名单 - whitelist / white / wl - 白名单

示例:

# 启用黑名单模式
/acl mode blacklist

# 启用白名单模式  
/acl mode whitelist

# 禁用黑白名单
/acl mode disabled

输出示例:

✅ 黑白名单模式已设置
========================================

🔧 当前模式: 黑名单

💡 说明: 黑名单模式,列表中的用户将被禁止访问
   使用 /acl add <用户ID> 添加到黑名单

2. 添加用户

/acl add <用户ID> [备注]

示例:

# 添加到黑名单(带原因)
/acl add USER123ABC 发送垃圾信息

# 添加到白名单(带备注)
/acl add VIPUSER001 VIP会员

# 添加用户(不带备注)
/acl add USER456DEF

输出示例:

✅ 用户已添加
========================================

👤 用户ID: USER123ABC
🔧 模式: 黑名单
📝 备注: 发送垃圾信息

⚠️ 该用户现在被禁止访问机器人

3. 移除用户

/acl remove <用户ID>

示例:

/acl remove USER123ABC

输出:

✅ 已从列表中移除用户: USER123ABC

4. 列出用户

/acl list

输出示例:

📋 黑白名单 - 黑名单模式
========================================

共 3 个用户:

1. USER123ABC
   备注: 发送垃圾信息

2. USER456DEF
   备注: 辱骂他人

3. USER789GHI

⚠️ 列表中的用户将被禁止访问

5. 清空列表

/acl clear

输出:

✅ 黑白名单已清空
========================================

🗑️  已移除 3 个用户

💡 黑白名单模式保持不变
   使用 /acl mode 修改模式

6. 查看统计

/acl stats

输出示例:

📊 黑白名单统计
========================================

🔧 当前模式: 黑名单
👥 用户数量: 5

⚠️  功能状态: 黑名单模式
   5 个用户被禁止访问

使用场景

场景 1: 封禁违规用户(黑名单)

问题: 有用户违反规则,需要封禁。

解决方案:

# 1. 启用黑名单模式
/acl mode blacklist

# 2. 添加违规用户
/acl add USER_SPAM 发送垃圾信息
/acl add USER_ABUSE 辱骂他人
/acl add USER_CHEAT 使用作弊工具

# 3. 查看封禁列表
/acl list

效果: - 被封禁的用户无法使用机器人 - 其他所有用户正常使用 - 可随时添加或移除封禁用户

场景 2: 内测阶段(白名单)

问题: 产品处于内测阶段,只允许测试人员使用。

解决方案:

# 1. 启用白名单模式
/acl mode whitelist

# 2. 添加测试人员
/acl add TESTER_001 核心测试员
/acl add TESTER_002 功能测试员
/acl add ADMIN_001 项目管理员

# 3. 查看测试人员列表
/acl list

效果: - 只有列表中的用户可以访问 - 其他所有用户被拒绝 - 适合控制访问范围

场景 3: 私有服务(白名单)

问题: 机器人仅供特定组织或群体使用。

解决方案:

# 1. 启用白名单模式
/acl mode whitelist

# 2. 添加组织成员
/acl add MEMBER_001 研发团队
/acl add MEMBER_002 产品团队
/acl add MEMBER_003 运营团队

# 3. 新成员加入时添加
/acl add MEMBER_004 新加入的成员

场景 4: 公测上线(禁用)

问题: 内测结束,需要对所有人开放。

解决方案:

# 1. 清空白名单
/acl clear

# 2. 禁用黑白名单
/acl mode disabled

效果: - 所有用户都可以访问 - 不再进行访问控制

API 使用

编程方式使用

package main

import (
    "github.com/KomeiDiSanXian/remilia/builtin/core/permission"
    "github.com/KomeiDiSanXian/remilia/plugin"
)

func main() {
    eng := engine.NewEngine()
    pm := plugin.NewManager(eng)

    // 注册权限插件
    pm.Register(permission.New())

    // 获取插件实例
    p := plugin.MustGetService[permission.Plugin](pm.GetContainer(), "permission")

    // 1. 设置黑名单模式
    p.SetACLMode(permission.ModeBlacklist)

    // 2. 添加用户到黑名单
    p.AddToACL("USER123", "违规用户")
    p.AddToACL("USER456", "垃圾信息")

    // 3. 检查用户是否允许访问
    allowed, reason := p.IsUserAllowed("USER123")
    if !allowed {
        println("用户被拒绝:", reason)
    }

    // 4. 列出所有用户
    users := p.ListACL()
    for _, user := range users {
        println("User:", user.UserID, "Note:", user.Note)
    }

    // 5. 移除用户
    p.RemoveFromACL("USER456")

    // 6. 获取统计信息
    stats := p.GetACLStats()
    println("Mode:", stats.Mode.String())
    println("Count:", stats.UserCount)
}

中间件集成

// 在全局中间件中使用
eng.Use(p.RequireACL())

// 或在特定命令中使用
eng.OnCommand(eventctx.EventPrivate, "/sensitive").
    Use(p.RequireACL()).
    Handle(handler)

技术实现

数据结构

// 访问控制列表
type AccessControlList struct {
    mu    sync.RWMutex       // 读写锁
    mode  ListMode           // 当前模式
    list  map[string]bool    // 用户列表
    notes map[string]string  // 用户备注
}

// 模式类型
type ListMode int

const (
    ModeDisabled   ListMode = iota  // 禁用
    ModeBlacklist                    // 黑名单
    ModeWhitelist                    // 白名单
)

访问检查逻辑

func (acl *AccessControlList) IsAllowed(userID string) (bool, string) {
    switch acl.mode {
    case ModeDisabled:
        // 禁用:允许所有用户
        return true, ""

    case ModeBlacklist:
        // 黑名单:只拒绝列表中的用户
        if acl.list[userID] {
            return false, "用户在黑名单中"
        }
        return true, ""

    case ModeWhitelist:
        // 白名单:只允许列表中的用户
        if acl.list[userID] {
            return true, ""
        }
        return false, "用户不在白名单中"
    }
}

测试

运行测试

cd builtin/core/permission
go test -v -run TestAccessControlList

测试覆盖: - ✅ 模式设置和获取 - ✅ 添加和移除用户 - ✅ 禁用模式访问检查 - ✅ 黑名单模式访问检查 - ✅ 白名单模式访问检查 - ✅ 用户列表查询 - ✅ 用户数量统计 - ✅ 清空列表 - ✅ 备注管理 - ✅ 统计信息 - ✅ 并发安全

测试结果: ✅ 全部通过(12个测试)

运行演示

# 查看 examples/showcase 中的 ACL 使用示例
cd examples/showcase
go run .

与其他功能的集成

1. 与权限系统集成

// 只有管理员可以管理黑白名单
if !permPlugin.HasPermissionEx(userID, "acl", "manage") {
    return errors.New("权限不足")
}

2. 与验证码系统集成

// 验证码验证前检查黑白名单
allowed, reason := permPlugin.IsUserAllowed(userID)
if !allowed {
    return errors.New("访问被拒绝: " + reason)
}

// 然后再进行验证码验证
role, err := permPlugin.VerifyAndGrantRole(code, userID)

3. 作为全局中间件

// 在所有命令前检查黑白名单
engine.Use(permPlugin.RequireACL())

// 这样所有命令都会自动检查访问权限

最佳实践

1. 黑名单使用建议

推荐: - 封禁违规用户 - 防止垃圾信息 - 临时禁止访问

不推荐: - 作为常规访问控制(应使用白名单) - 封禁大量用户(影响性能)

2. 白名单使用建议

推荐: - 内测阶段 - 私有服务 - 严格的访问控制

不推荐: - 公开服务 - 频繁添加移除用户

3. 模式切换建议

# 开发阶段:禁用(方便测试)
/acl mode disabled

# 内测阶段:白名单(控制范围)
/acl mode whitelist

# 公测/正式:禁用或黑名单(开放访问,封禁违规)
/acl mode disabled
# 或
/acl mode blacklist

4. 备注规范

建议的备注格式:

# 黑名单备注(记录原因)
发送垃圾信息
辱骂他人
使用作弊工具

# 白名单备注(记录身份)
VIP会员
核心测试员
项目管理员

性能考虑

  • 内存占用: 每个用户约 100 字节
  • 查询性能: O(1) 哈希表查询
  • 并发性能: 读写锁,支持高并发读取
  • 适用规模:
  • 黑名单: < 10,000 用户
  • 白名单: < 1,000 用户

常见问题

Q: 可以同时使用黑名单和白名单吗?

A: 不可以。系统同时只能处于一种模式:禁用、黑名单或白名单。

Q: 切换模式会清空列表吗?

A: 不会。切换模式只改变访问控制逻辑,列表内容保持不变。如需清空请使用 /acl clear

Q: 如何导入/导出黑白名单?

A: 当前版本不支持直接导入导出。建议使用脚本批量添加,或通过数据库备份。

Q: 黑白名单会影响性能吗?

A: 影响很小。使用哈希表进行 O(1) 查询,且有读写锁优化并发访问。

Q: 管理员也会受黑白名单限制吗?

A: 是的。建议在白名单模式下首先添加管理员用户ID。

未来改进

  • 导入/导出功能
  • 批量操作(批量添加/移除)
  • 正则表达式匹配
  • IP地址黑白名单
  • 时间限制(临时封禁)
  • 自动解封
  • 审计日志