封禁帳號是一個比較常見的業務需求,尤爲是在論壇、社區類型的項目中,當出現了違規用戶時咱們須要將其帳號當即封禁。java
常規的設計思路是:在設計用戶表
時增長一個狀態字段,例如:status
,其值爲1時表明帳號正常,其值爲0時表明帳號已被封禁。git
當咱們須要封禁一個帳號時,只須要將其帳號的status
值修改成0便可,對方再次登陸系統時,咱們即可以檢測到status
值不爲1禁止登陸。github
這種模式雖然思路簡單,但也有一個不小的問題,那就是: 若是對方一直在線不註銷登陸呢?spring
因爲咱們只在登陸時檢測status
值,這也就表明:若是對方不主動註銷帳號,他的會話仍是會一直存在且有效。數據庫
那怎麼才能夠作到在封禁帳號後當即生效?緩存
你可能會想到使用攔截器,攔截用戶的全部請求檢測帳號狀態:status=0
時禁止訪問,status=1
時再對請求放行app
此方式雖然解決了問題,可是若是每次請求都要進行數據庫查詢的話,數據庫表示你如此掃蕩我你就沒有一點心理壓力嗎?框架
那怎麼辦?上緩存?雖然能夠緩解性能壓力,但彷佛總感受沒有完美解決問題。spring-boot
真正的問題點在於:一個正常的系統只有0.01%的用戶是須要封禁的,咱們對其它99.99%用戶的實時檢測都是沒必要要的性能浪費。性能
在如上場景中,咱們真正須要的是一個踢人下線的操做,即:咱們須要在封禁某個用戶後,使他的會話當即掉線,即時他從新登陸也會被禁止登陸
那麼,怎麼作到實時踢人下線呢?
筆者使用的是sa-token
權限認證框架,這個框架封裝了踢人下線操做調用很是方便,不用像其它框架同樣還須要我本身再封裝一層才能作到。
pom.xml
框架<!-- sa-token 權限認證, 在線文檔:http://sa-token.dev33.cn/ --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.12.1</version> </dependency>
@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帳號的會話註銷登陸,對方再次訪問系統時會拋出`NotLoginException`異常,場景值爲-5 @RequestMapping("kickout") public String kickout(long userId) { StpUtil.logoutByLoginId(userId); return "剔出成功"; }
關鍵代碼就在 StpUtil.logoutByLoginId(userId)
這一句,使指定id的帳號註銷登陸 (踢人下線)
若是以爲文章寫得不錯還請你們不要吝惜爲文章點個贊,您的支持是我更新的最大動力!
最後附上項目連接: