需要场景

封禁账号是一个比拟常见的业务需要,尤其是在论坛、社区类型的我的项目中,当呈现了违规用户时咱们须要将其账号立刻封禁。

惯例的设计思路是:在设计用户表时减少一个状态字段,例如:status,其值为1时代表账号失常,其值为0时代表账号已被封禁。

当咱们须要封禁一个账号时,只须要将其账号的status值批改为0即可,对方再次登录零碎时,咱们便能够检测到status值不为1禁止登录。

这种模式尽管思路简略,但也有一个不小的问题,那就是: 如果对方始终在线不登记登录呢?

因为咱们只在登录时检测status值,这也就代表:如果对方不被动登记账号,他的会话还是会始终存在且无效。

那怎么才能够做到在封禁账号后立刻失效?

你可能会想到应用拦截器,拦挡用户的所有申请检测账号状态:status=0时禁止拜访,status=1时再对申请放行

此形式尽管解决了问题,然而如果每次申请都要进行数据库查问的话,数据库示意你如此涤荡我你就没有一点心理压力吗?

那怎么办?上缓存?尽管能够缓解性能压力,但仿佛总感觉没有完满解决问题。

真正的问题点在于:一个失常的零碎只有0.01%的用户是须要封禁的,咱们对其它99.99%用户的实时检测都是不必要的性能节约。

在如上场景中,咱们真正须要的是一个踢人下线的操作,即:咱们须要在封禁某个用户后,使他的会话立刻掉线,即时他从新登录也会被禁止登录

那么,怎么做到实时踢人下线呢?

笔者应用的是sa-token权限认证框架,这个框架封装了踢人下线操作调用十分不便,不必像其它框架一样还须要我本人再封装一层能力做到。

具体代码

首先增加pom.xml框架

cn.dev33
sa-token-spring-boot-starter
1.12.1

复制代码

在用户登录时将账号id写入会话中

@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("doLogin")
public String doLogin(String username, String password) {
// 此处仅作示例模仿,实在我的项目须要从数据库中查问数据进行比对
if("zhang".equals(username) && "123456".equals(password)) {
StpUtil.setLoginId(10001);
return "登录胜利";
}
return "登录失败";
}
}

复制代码

将指定id的账号

// 使指定id账号的会话登记登录,对方再次拜访零碎时会抛出`NotLoginException`异样,场景值为-5
@RequestMapping("kickout")
public String kickout(long userId) {
StpUtil.logoutByLoginId(userId);
return "剔出胜利";
}

复制代码

要害代码就在 StpUtil.logoutByLoginId(userId) 这一句,使指定id的账号登记登录 (踢人下线)

参考:《2020最新Java根底精讲视频教程和学习路线!》

作者:省长