用户模块-黑名单技术方案博客

一、背景与目标

        在一个开放的系统中,用户可以自由发表言论,这虽然增加了互动性,但也可能带来一些问题,比如恶意发言、骚扰其他用户等。为了维护平台秩序,我们需要一种机制,来限制这类用户的行为。

因此,我们设计了一个“黑名单”功能,主要目标是:

  • 限制违规用户的行为,比如不能发送消息、不能加入群聊等;

  • 屏蔽恶意用户的设备或网络,通过拉黑IP来防止换号继续骚扰;

  • 确保系统能快速判断一个用户是否被拉黑,并及时做出拦截响应。

        这个黑名单功能需要配合权限系统使用,只有特定身份的用户(比如管理员)才能对其他用户进行拉黑操作,防止滥用。

二、权限与角色解耦设计

        在实际系统中,我们不能让所有用户都拥有“拉黑别人”的权限。比如,普通用户不能拉黑别人,但管理员可以。因此,我们需要一个权限控制机制

这个机制我们分成三层:

  1. 用户(User):就是登录系统的每个用户。

  2. 角色(Role):比如“普通用户”、“群聊管理员”、“超级管理员”。

  3. 权限(Permission):比如“拉黑别人”、“删除消息”、“踢人”。

每个用户可以拥有一个或多个角色,每个角色可以拥有多个权限。这样做有两个好处:

  • 更灵活:不用给每个用户单独配置权限,只要分配角色就行。

  • 更清晰:权限管理结构简单,方便维护。

在系统中,我们会写一个专门的服务叫做 hasPower 方法,用来判断某个用户是否拥有某个权限。比如:

hasPower(用户ID, “拉黑权限”)

如果返回 true,说明这个用户可以拉黑别人。

        为了提高效率,我们会把用户的角色和权限信息缓存到Redis里,这样查询速度会更快,尤其在用户刚登录的时候就把权限加载好。

三、黑名单设计概述

        黑名单的作用很简单:把一些不守规矩的用户或者IP地址标记出来,禁止他们继续使用系统功能

        在设计上,我们准备了一个专门的黑名单表,里面记录了被拉黑的内容。这个表里主要有两个重要字段:

  • type(类型):表示是拉黑的用户,还是拉黑的IP地址

    • 比如:UID 表示用户ID,IP 表示某个IP地址。

  • target(目标):具体被拉黑的内容

    • 如果是用户,就存用户的ID;如果是IP,就存这个IP地址。

为什么不仅要拉黑用户ID,还要拉黑IP呢?
因为有些用户可能换小号继续捣乱,但如果他们用的是同一个IP,就能一起拦住,防止继续违规。

每次有人被拉黑,我们就往黑名单表里插入一条或多条数据,分别是:

  • 用户ID

  • 登录时的两个IP(注册IP、最后登录IP)

        这些数据都会提前缓存到 Redis 中,这样系统在收到请求时能快速判断这个用户或IP是否在黑名单中。

四、黑名单接口实现

        在系统中,我们需要有一个接口来拉黑用户,这就是我们需要实现的“黑名单接口”。这个接口的主要任务是:

  1. 接收要拉黑的用户ID

  2. 判断调用接口的用户是否有权限拉黑

  3. 将该用户和他们的IP地址添加到黑名单表中

1. 接口输入与权限判断

        首先,调用拉黑接口的人必须有权限。比如,只有管理员才能拉黑用户。所以,接口开始时,我们会检查一下调用者的权限,确认他们是不是有“拉黑别人”的权限。

boolean hasPermission = permissionService.hasPower(currentUserId, "拉黑权限");
if (!hasPermission) {
    return "没有权限进行此操作";
}

2. 拉黑操作

        权限通过后,接下来就是“拉黑”操作。拉黑的内容不仅包括用户ID,还包括该用户的IP地址。如果该用户有多个IP登录,我们会将所有IP一起拉黑。

blacklistService.addToBlacklist(userId, userIp);

3. 异步推送

        为了提高效率,拉黑后我们将这次操作包装成一个事件,后续通过异步线程池推送到其他系统,比如通知相关人员或其他服务。

  • 通过一个线程池来处理这些推送任务,可以让系统运行更快,不会因为等待推送任务而阻塞主操作。

executorService.submit(() -> {
    pushToOtherServices(blacklistEvent);
});

4. 错误处理

        有时可能会发生一些错误,比如拉黑的用户已经被拉黑了,我们需要通过 try-catch 来处理这些错误,避免系统崩溃。

try {
    blacklistService.addToBlacklist(userId, userIp);
} catch (Exception e) {
    return "拉黑失败:" + e.getMessage();
}

5. 返回结果

最后,接口会返回一个成功消息或错误信息,前端根据这些信息更新界面。

return "用户已成功拉黑";

通过这样的接口设计,我们不仅确保了拉黑操作的安全性,还优化了系统的处理速度。

五、黑名单拦截机制

        黑名单功能的核心就是在用户请求时,检查他们是否被拉黑。为了确保每次请求都能快速判断,我们使用了拦截器

1. 什么是拦截器?

        拦截器可以看作是一个“守门员”,在每个请求进入系统之前,它会先检查是否符合条件。如果不符合,就可以拒绝请求,返回一个错误信息。

2. 拦截器实现

        我们为黑名单检查专门创建了一个拦截器,叫做 BlankInterceptor。每当用户发起请求时,BlankInterceptor 会:

  • 先从缓存中获取当前用户的ID和IP

  • 判断这些信息是否在黑名单中。

  • 如果在黑名单中,就直接拦截请求,返回错误码和错误信息。

  • 如果不在黑名单中,才允许请求继续进行。

3. 检查逻辑

        在拦截器中,我们会查找用户的ID和IP是否在Redis缓存中的黑名单列表里。如果用户被拉黑,系统会返回一个提示信息,比如:“您已被拉黑,无法进行此操作。”

boolean isBlacklisted = blacklistService.isUserBlacklisted(userId, userIp);
if (isBlacklisted) {
    return "您的账号已被拉黑,无法继续操作";
}

4. 拦截器配置

        为了让这个拦截器生效,我们需要在配置文件中注册并启用它。这样,每当用户发起请求时,拦截器就会自动执行。

5. 缓存更新

        当用户的黑名单状态发生变化(比如被拉黑或解除拉黑),我们需要及时更新缓存。这样可以确保系统始终使用最新的黑名单数据。

如果用户的状态变动,我们会使用类似以下代码来更新缓存:

6. 错误处理

        有时可能会出现一些小问题,比如IP和用户ID重复拉黑,导致错误。为了避免系统崩溃,我们在拦截器中添加了错误捕获机制(try-catch),确保即使出现问题,也能正常运行。

try {
    // 拉黑检查
} catch (Exception e) {
    return "系统错误,请稍后再试";
}

        这样,黑名单的拦截机制就完成了,每次请求都会经过这个“守门员”的检查,确保不允许黑名单中的用户继续操作。

六、前端联动逻辑

        前端的任务是根据后台返回的信息,及时更新用户界面,确保用户知道自己是否被拉黑,并做出相应的反应。

1. 拉黑后的反馈

        当后台成功拉黑用户时,系统会返回拉黑操作的结果,前端接收到这个信息后,要做出相应的显示。比如:

  • 成功拉黑:提示“该用户已被拉黑”。

  • 失败拉黑:提示“拉黑失败,请稍后再试”。

前端可以在用户列表中立即隐藏被拉黑的用户,或者将其状态更新为“已拉黑”。

2. 用户请求的拦截

        如果被拉黑的用户尝试进行操作,比如发送消息或加入群聊,系统会通过拦截器阻止该请求。后台会返回一个错误信息,告诉用户自己被拉黑了。

前端收到这个错误信息后,可以做以下几件事:

  • 弹出提示框:告诉用户“您已被拉黑,无法继续操作”。

  • 界面更新:在用户列表中把这个用户的状态标记为“拉黑”。

例如:

if (response.errorCode === 'BLACKLISTED') {
    alert('您已被拉黑,无法继续操作');
    // 更新UI,显示用户已拉黑状态
}

3. 拉黑与解除拉黑后的本地更新

        当用户被拉黑或解除拉黑时,前端需要实时更新界面。如果是被拉黑的用户,在接收到后台返回的拉黑信息后,前端会:

  • 删除消息:从本地的聊天记录中移除拉黑用户的消息。

  • 更新状态:将该用户的状态标记为“已拉黑”,防止他们继续参与互动。

如果是解除拉黑,前端会显示“用户已解除拉黑”,并允许其继续正常操作。

4. 动态刷新

        为了提高用户体验,前端可以定时刷新黑名单状态,保证前端界面上的黑名单信息与后台的数据一致。这样就算后台数据发生了变化,前端也能及时更新。

5. 提醒与提示

        前端还可以通过弹出窗口或提示框,提醒用户被拉黑的后果,帮助用户理解为什么被拉黑,避免引发不必要的误会。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值