一個(gè)登錄功能也能玩出這么多花樣?sa-token帶你輕松搞定多地登錄、單地登錄、同端互斥登錄

需求場景

說起登錄,你可能會不屑一顧,還有比這更簡單的功能嗎?

獲取一下用戶提交參數(shù) username + password 和數(shù)據(jù)庫中一比對,有記錄返回[登錄成功],無記錄返回[用戶名或密碼錯(cuò)誤]

什么,就這?

當(dāng)你熟練的打包、部署、啟動項(xiàng)目開始了一天的摸魚之后,產(chǎn)品經(jīng)理開始坐不住了

“小順子啊,你看咱們的APP登錄能不能加一個(gè)功能,就是那種......那個(gè)......一個(gè)用戶登錄之后,能把上一個(gè)登錄的自動擠下線”

此時(shí)的你陷入了沉思,怎么讓他在登錄之后,把上一個(gè)登錄者的會話給擠下線呢?

難道說要在每次登錄之后循環(huán)一遍Session列表,找到與此用戶同賬號的會話將其注銷,聰明如你馬上想到了這種方案將會給服務(wù)器帶來巨大的性能壓力!

那怎么辦?難道要建個(gè)Map以userId做key、Session做value,建立起映射關(guān)系,然后手動取出Session做上標(biāo)記[已被擠下線]?

說干就干,當(dāng)你擼起袖子,噼里啪啦敲好上述邏輯之后,然后測試、打包、部署、上傳一氣呵成,又開始了一天的摸魚......

然而你還是低估了產(chǎn)品經(jīng)理的腦洞能力

“小順子,你看你寫的功能有點(diǎn)小問題啊,我每次一登錄,就會把其它登錄地給擠掉線啊?!?/p>

此時(shí)的你下意識反駁到: "有什么問題?這難道不就是你想要的效果嗎?"

“en....就是....咱們能不能這樣,我在手機(jī)上登錄,能不能只把別的手機(jī)上給擠下線,但是我電腦上已經(jīng)登錄的不受影響”

“擠掉肯定是全部擠掉啊,怎么可能只留下你電腦端不擠掉呢?你要的功能不可能做到”

只見此時(shí)產(chǎn)品經(jīng)理嘴角輕輕一笑,放出了大招:

“那人家騰訊QQ是怎么做到的呢?”

一句話暴擊99999+,頓時(shí)你啞口無言,是呀,騰訊QQ怎么做到這種功能的呢?一個(gè)QQ號可以在手機(jī)和電腦上同時(shí)在線,但是卻不能兩個(gè)手機(jī)同時(shí)在線

難道說在登錄時(shí)再記錄時(shí)每次登錄的設(shè)備標(biāo)識?循環(huán)檢測登錄列表的設(shè)備名稱,同設(shè)備擠下線,不同設(shè)備保持登錄?

產(chǎn)品經(jīng)理沖上咖啡,帶著勝利的微笑離開了房間,只留下一臉愁容的你,冥思苦想著實(shí)現(xiàn)方案……


正題

好了,說了這么多,下面進(jìn)入今天的主題————sa-token,一個(gè)可以讓你輕松解決各種登錄問題的權(quán)限認(rèn)證框架!

如上述場景所言,你遇到的問題不過是三個(gè)典型的登錄模型:多地登錄、單地登錄、同端互斥登錄

  • 多地登錄:指同一賬號可以在任意地點(diǎn)同時(shí)登錄,互不影響
  • 單地登錄:在同一時(shí)間一個(gè)賬號只能在一個(gè)地點(diǎn)登錄,新登錄會擠掉舊登錄者
  • 同端互斥登錄:在同一類型設(shè)備上只允許單地點(diǎn)登錄,在不同類型設(shè)備上允許同時(shí)在線

接下來讓我們看看使用sa-token是如何輕松處理這三種登錄問題的

多地登錄

此模式較為簡單,sa-token默認(rèn)模式即為多地登錄模式

  1. 首先添加pom.xml框架
<!-- sa-token 權(quán)限認(rèn)證, 在線文檔:http://sa-token.dev33.cn/ -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.12.1</version>
</dependency>
  1. 在用戶登錄時(shí)將賬號id寫入會話中
@RestController
@RequestMapping("user")
public class UserController {
    @RequestMapping("doLogin")
    public String doLogin(String username, String password) {
        // 此處僅作示例模擬,真實(shí)項(xiàng)目需要從數(shù)據(jù)庫中查詢數(shù)據(jù)進(jìn)行比對 
        if("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.setLoginId(10001);
            return "登錄成功";
        }
        return "登錄失敗";
    }
}
  1. 新建啟動類啟動
@SpringBootApplication
public class SaTokenDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SaTokenDemoApplication.class, args); 
        System.out.println("\n啟動成功:sa-token配置如下:" + SaTokenManager.getConfig());
    }
}

至此,我們已經(jīng)完成了多地點(diǎn)登錄的全部代碼,上述代碼在多人登錄同一賬號時(shí)將不會對舊會話做任何處理,同一賬號可以在多個(gè)地點(diǎn)任意登錄,互不影響

單地登錄

單地登錄多地登錄唯一的差異就是, 需要改一下yml配置文件

spring: 
    # sa-token配置
    sa-token: 
        allow-concurrent-login: false

配置項(xiàng) allow-concurrent-login 的含義為:是否允許同一賬號并發(fā)登錄 (此值為true時(shí)允許一起登錄, 為false時(shí)新登錄擠掉舊登錄)

其它代碼與[多地登錄]無異,當(dāng)我們在兩個(gè)瀏覽器分別登錄同一賬號時(shí),舊會話再次訪問系統(tǒng)將會得到如下提示:

{
    "code": 401,
    "msg": "token已被頂下線",
    "data": null,
    "dataCount": null
}

同端互斥登錄

好了,終于到了最終難題,同端互斥登錄可以讓我們像騰訊QQ一樣,在同一類型設(shè)備上只允許單地點(diǎn)登錄,在不同類型設(shè)備上允許同時(shí)在線

那么在sa-token中如何做到同端互斥登錄呢?

首先如單地登錄一樣,在配置文件中,將 allowConcurrentLogin 配置為false,然后調(diào)用登錄等相關(guān)接口時(shí)聲明設(shè)備標(biāo)識即可:

指定設(shè)備標(biāo)識登錄
StpUtil.setLoginId(10001, "PC");    

調(diào)用此方法登錄后,同設(shè)備的會被頂下線(不同設(shè)備不受影響),再次訪問系統(tǒng)時(shí)會拋出 NotLoginException 異常,場景值=-4

指定設(shè)備標(biāo)識強(qiáng)制注銷(踢人下線)
StpUtil.logoutByLoginId(10001, "PC");       

如果第二個(gè)參數(shù)填寫null或不填,代表將這個(gè)賬號id所有在線端踢下線,被踢出者再次訪問系統(tǒng)時(shí)會拋出 NotLoginException 異常,場景值=-5

查詢當(dāng)前登錄的設(shè)備標(biāo)識
StpUtil.getLoginDevice(); 

結(jié)尾

以上就是sa-token框架在處理登錄問題時(shí)的各種技巧,可以看出不管是簡單的多地登錄還是復(fù)雜的同端互斥登錄,在sa-token都有完成的解決方案

sa-token是近期開源的國產(chǎn)優(yōu)秀權(quán)限認(rèn)證框架,除了各種登錄認(rèn)證,sa-token還可以輕松解決項(xiàng)目中的各種權(quán)限認(rèn)證問題,
比如:踢人下線、自動續(xù)簽、身份臨時(shí)切換等常見業(yè)務(wù)均可以一行代碼調(diào)用實(shí)現(xiàn),接下來的文章我會逐一介紹這些特性,讓大家對sa-token有一個(gè)全面的了解

如果覺得文章寫得不錯(cuò)還請大家不要吝惜為文章點(diǎn)個(gè)贊,您的支持是我更新的最大動力!

最后附上項(xiàng)目鏈接:





?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容