最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用Sa-Token框架完成踢人下線功能

 更新時間:2023年05月10日 09:54:26   作者:省長  
踢人下線是一個很常見的需求,本文主要介紹了Java使用Sa-Token框架完成踢人下線功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、需求

在企業(yè)級項目中,踢人下線是一個很常見的需求,如果要設(shè)計比較完善的話,至少需要以下功能點:

  • 可以根據(jù)用戶 userId 踢出指定會話,對方再次訪問系統(tǒng)會被提示:您已被踢下線,請重新登錄。
  • 可以查詢出一個賬號共在幾個設(shè)備端登錄,并返回其對應的 Token 憑證,以便后續(xù)操作。
  • 可以只踢出一個賬號某一個端的會話,其他端不受影響。例如在某電商APP上可以看到當前賬號共在幾個手機上登錄,并注銷指定端的會話,當前端不受影響。

手動從零開始設(shè)計滿足需求的會話架構(gòu),還是需要一定的代碼量的。本篇將介紹如何使用 Sa-Token 方便的完成上述需求,Sa-Token 框架對踢人下線做了較為完整的封裝,我們可以使用極少的代碼就完成踢人下線功能。

Sa-Token 是一個輕量級 java 權(quán)限認證框架,主要解決登錄認證、權(quán)限認證、單點登錄、OAuth2、微服務(wù)網(wǎng)關(guān)鑒權(quán) 等一系列權(quán)限相關(guān)問題。Gitee 開源地址:gitee.com/dromara/sa-token

首先在項目中引入 Sa-Token 依賴:

<!-- Sa-Token 權(quán)限認證 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

注:如果你使用的是 SpringBoot 3.x,只需要將 sa-token-spring-boot-starter 修改為 sa-token-spring-boot3-starter 即可。

二、踢人下線 API 一覽

先看看 Sa-Token 為我們提供的與踢人下線有關(guān)的API。

強制注銷:

StpUtil.logout(10001);                    // 強制指定賬號注銷下線 
StpUtil.logout(10001, "PC");              // 強制指定賬號指定端注銷下線 
StpUtil.logoutByTokenValue("token");      // 強制指定 Token 注銷下線 

踢人下線:

StpUtil.kickout(10001);                    // 將指定賬號踢下線 
StpUtil.kickout(10001, "PC");              // 將指定賬號指定端踢下線
StpUtil.kickoutByTokenValue("token");      // 將指定 Token 踢下線

強制注銷 和 踢人下線 的區(qū)別在于:

  • 強制注銷等價于對方主動調(diào)用了注銷方法,再次訪問會提示:Token無效。
  • 踢人下線不會清除Token信息,而是將其打上特定標記,再次訪問會提示:Token已被踢下線。

動態(tài)圖演示:

強制注銷 和 踢人下線

下面開始進行代碼實戰(zhàn)。

三、根據(jù)賬號踢人下線

在完成踢人下線之前,我們需要先讓會話完成登錄。正常的登錄需要根據(jù) username + password 判斷賬號合法性,由于我們本篇的重點是 踢人下線,所以此處簡化一下登錄操作,直接填入 userId 進行登錄。

package com.pj;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 測試踢人下線
 */
@RestController
@RequestMapping("/kick/")
public class KickController {
    // 會話登錄接口  ---- http://localhost:8081/kick/doLogin?id=10001
    @RequestMapping("doLogin")
    public SaResult doLogin(long userId) {
        StpUtil.login(userId);
        return SaResult.ok("登錄成功,Token 憑證為:" + StpUtil.getTokenValue());
    }
    // 驗證當前客戶端是否登錄  ---- http://localhost:8081/kick/checkLogin
    @RequestMapping("checkLogin")
    public SaResult checkLogin() {
        StpUtil.checkLogin();
        // 下面是登錄后才會返回的數(shù)據(jù)
        return SaResult.ok("您已登錄成功,userId=" + StpUtil.getLoginId());
    }
    // 根據(jù)賬號Id踢人下線  ---- http://localhost:8081/kick/kickout
    @RequestMapping("kickout")
    public SaResult kickout(long userId) {
        StpUtil.kickout(userId);
        return SaResult.ok("將賬號 " + userId + " 踢下線成功");
    }
    // 全局異常攔截
    @ExceptionHandler
    public SaResult handlerException(Exception e) {
        e.printStackTrace();
        return SaResult.error(e.getMessage());
    }
}

運行代碼,分別用三個獨立的瀏覽器測試登錄:

// 使用瀏覽器 1 測試登錄賬號 10001
http://localhost:8081/kick/doLogin?userId=10001
// 使用瀏覽器 2 測試登錄賬號 10002
http://localhost:8081/kick/doLogin?userId=10002
// 使用瀏覽器 3 測試登錄賬號 10003
http://localhost:8081/kick/doLogin?userId=10003

之所以使用三個獨立的瀏覽器來測試,是為了避免會話的相互覆蓋,造成邏輯不可控。訪問成功的話,服務(wù)端的返回信息會類似如下:

{
	"code": 200,
	"msg": "登錄成功,Token 憑證為:f53ac098-aed4-4de2-9223-8c3f1dab656d",
	"data": null
}

然后使用三個瀏覽器分別訪問登錄驗證接口:http://localhost:8081/kick/checkLogin復制代碼

返回信息如下:

{
	"code": 200,
	"msg": "您已登錄成功,userId=10001",
	"data": null
}

現(xiàn)在開始測試踢人下線,使用任意瀏覽器訪問:http://localhost:8081/kick/kickout?userId=10002復制代碼

返回信息:

{
	"code": 200,
	"msg": "將賬號 10002 踢下線成功",
	"data": null
}

賬號 10002 將被踢下線成功,現(xiàn)在我們再使用瀏覽器2 測試一下 10002 是否仍然在線:

{
	"code": 500,
	"msg": "Token已被踢下線:aa5911a6-3623-4fdb-98d0-055c46353981",
	"data": null
}

可以看到,10002會話已失效,無法通過登錄校驗。

四、根據(jù) Token 踢人下線

業(yè)務(wù)場景舉例:我要在APP上查看我的賬號共在幾個設(shè)備登錄,并且將除我之外的設(shè)備全部踢下線。

首先我們需要在 application.yml 中添加配置:

sa-token: 
    is-share: false

is-share 的含義是:在多人登錄同一賬號時,是否共用同一個 Token:

  • 此值為 true 時,所有登錄共用一個Token。
  • 此值為 false 時,每次登錄新建一個Token。

在以上 KickController 的基礎(chǔ)上,繼續(xù)添加接口:

/**
 * 測試踢人下線
 */
@RestController
@RequestMapping("/kick/")
public class KickController {
	// 其他代碼...
	// 以下是需要新添加的代碼
    // 查詢我的賬號已經(jīng)在幾個設(shè)備登錄  ---- http://localhost:8081/kick/tokenList
    @RequestMapping("tokenList")
    public SaResult tokenList() {
        long currUserId = StpUtil.getLoginIdAsLong();
        List<String> tokenList = StpUtil.getTokenValueListByLoginId(currUserId);
        return SaResult.data(tokenList);
    }
    // 根據(jù) Token 踢人下線  ---- http://localhost:8081/kick/kickoutToken?token=xxxx
    @RequestMapping("kickoutToken")
    public SaResult kickoutToken(String token) {
        StpUtil.kickoutByTokenValue(token);
        return SaResult.ok("將Token: " + token + " 踢下線成功");
    }
}

重啟項目(如果集成 Redis 了就清空 Redis數(shù)據(jù)一下),分別從三個獨立的瀏覽器測試訪問:http://localhost:8081/kick/doLogin?userId=10001復制代碼

返回如下:

{
	"code": 200,
	"msg": "登錄成功,Token 憑證為:450b8b73-f52d-4496-b67e-bdd579c8708a",
	"data": null
}

仔細觀察三個瀏覽器返回的信息,雖然三個瀏覽器都是登錄賬號 10001,但是每次返回的 Token 憑證都是不一樣的。

現(xiàn)在查詢一下當前賬號一共在幾個設(shè)備完成了登錄:http://localhost:8081/kick/tokenList復制代碼

返回如下:

{
	"code": 200,
	"msg": "ok",
	"data": [
		"450b8b73-f52d-4496-b67e-bdd579c8708a",
		"39d7974b-327d-4aea-a0b7-d90ab47caf0c",
		"d73c1bc5-d04f-4dc2-81ee-42c9438f9d78"
	]
}

現(xiàn)在選一個 Token,將其踢下線:http://localhost:8081/kick/kickoutToken?token=d73c1bc5-d04f-4dc2-81ee-42c9438f9d78復制代碼

返回信息如下:

{
	"code": 200,
	"msg": "將Token: d73c1bc5-d04f-4dc2-81ee-42c9438f9d78 踢下線成功",
	"data": null
}

然后在對應的瀏覽器,驗證一下登錄狀態(tài):http://localhost:8081/kick/checkLogin復制代碼

返回如下:

{
	"code": 500,
	"msg": "Token已被踢下線:d73c1bc5-d04f-4dc2-81ee-42c9438f9d78",
	"data": null
}

可以看到,該設(shè)備登錄的會話已被踢下線。那么同賬號的其他設(shè)備有沒有受到影響呢,我們從其他瀏覽器驗證一下:http://localhost:8081/kick/checkLogin復制代碼

返回如下:

{
	"code": 200,
	"msg": "您已登錄成功,userId=10001",
	"data": null
}

可以看到,只有踢出的 Token 被強制下線了,其他端并沒有受到影響。

參考資料

到此這篇關(guān)于Java使用Sa-Token框架完成踢人下線功能的文章就介紹到這了,更多相關(guān)Sa-Token 踢人下線內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于StringUtils.isBlank()的使用及說明

    關(guān)于StringUtils.isBlank()的使用及說明

    這篇文章主要介紹了關(guān)于StringUtils.isBlank()的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Java實現(xiàn)二叉樹的示例代碼(遞歸&迭代)

    Java實現(xiàn)二叉樹的示例代碼(遞歸&迭代)

    二叉樹(Binary?tree)是樹形結(jié)構(gòu)的一個重要類型。本文將利用Java語言實現(xiàn)二叉樹,文中的示例代碼講解詳細,需要的同學可以參考一下
    2022-03-03
  • java如何更改數(shù)據(jù)庫中的數(shù)據(jù)

    java如何更改數(shù)據(jù)庫中的數(shù)據(jù)

    這篇文章主要介紹了java如何更改數(shù)據(jù)庫中的數(shù)據(jù),修改數(shù)據(jù)庫是數(shù)據(jù)庫操作必不可少的一部分,使用Statement接口中的excuteUpdate()方法可以修改數(shù)據(jù)表中的數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • 從零開始Java實現(xiàn)Parser?Combinator

    從零開始Java實現(xiàn)Parser?Combinator

    這篇文章主要為大家介紹了從零開始Java實現(xiàn)Parser?Combinator過程及原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • Java NIO Buffer過程詳解

    Java NIO Buffer過程詳解

    這篇文章主要介紹了Java NIO Buffer過程詳解,緩沖區(qū)在java nio中負責數(shù)據(jù)的存儲。緩沖區(qū)就是數(shù)組。用于存儲不同數(shù)據(jù)類型的數(shù)據(jù)。,需要的朋友可以參考下
    2019-06-06
  • Java中多個線程交替循環(huán)執(zhí)行的實現(xiàn)

    Java中多個線程交替循環(huán)執(zhí)行的實現(xiàn)

    有些時候面試官經(jīng)常會問,兩個線程怎么交替執(zhí)行呀,本文就來詳細的介紹一下Java中多個線程交替循環(huán)執(zhí)行的實現(xiàn),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • java中File類的使用方法

    java中File類的使用方法

    本篇文章介紹了,在java中File類的使用方法。需要的朋友參考下
    2013-04-04
  • Java中BEAN與EJB的區(qū)別淺析

    Java中BEAN與EJB的區(qū)別淺析

    這篇文章主要介紹了Java中BEAN與EJB的區(qū)別淺析,本文總結(jié)了它們之間的不同之處,需要的朋友可以參考下
    2015-03-03
  • 使用JAVA實現(xiàn)高并發(fā)無鎖數(shù)據(jù)庫操作步驟分享

    使用JAVA實現(xiàn)高并發(fā)無鎖數(shù)據(jù)庫操作步驟分享

    一個在線2k的游戲,每秒鐘并發(fā)都嚇死人。傳統(tǒng)的hibernate直接插庫基本上是不可行的。我就一步步推導出一個無鎖的數(shù)據(jù)庫操作,詳情看下文
    2013-11-11
  • java實現(xiàn)jframe透明窗體示例

    java實現(xiàn)jframe透明窗體示例

    這篇文章主要介紹了java實現(xiàn)jframe透明窗體示例,需要的朋友可以參考下
    2014-03-03

最新評論

江山市| 庆元县| 青海省| 石林| 蚌埠市| 宣威市| 牟定县| 平远县| 铜陵市| 肃宁县| 重庆市| 修水县| 澄城县| 阜城县| 邓州市| 南岸区| 溆浦县| 布拖县| 冀州市| 喀什市| 阿拉善左旗| 南召县| 马鞍山市| 错那县| 武安市| 朔州市| 宝应县| 鹿邑县| 宝丰县| 集安市| 牙克石市| 邯郸县| 四川省| 封开县| 同江市| 安吉县| 婺源县| 锡林浩特市| 大连市| 虹口区| 习水县|