From 631db8215f99977b2305aff3494920d4e82155a9 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Wed, 19 Mar 2025 12:03:30 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=AE=8C=E5=96=84=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=AB=A0=E8=8A=82=E6=96=87=E6=A1=A3=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=95=E8=B4=A6=E5=8F=B7=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=9A=84=E6=93=8D=E4=BD=9C=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pj/test/LoginController.java | 17 +++++- .../main/java/com/pj/test/TestController.java | 30 ++++++---- sa-token-doc/up/search-session.md | 56 +++++++++++++++---- 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java index 56529460..02440fdd 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/LoginController.java @@ -1,11 +1,14 @@ package com.pj.test; +import cn.dev33.satoken.session.SaTerminalInfo; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.util.SaResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + /** * 登录测试 * @author click33 @@ -45,7 +48,19 @@ public class LoginController { public SaResult tokenInfo() { return SaResult.data(StpUtil.getTokenInfo()); } - + + // 查询账号登录设备信息 ---- http://localhost:8081/acc/terminalInfo + @RequestMapping("terminalInfo") + public SaResult terminalInfo() { + System.out.println("账号 10001 登录设备信息:"); + List terminalList = StpUtil.getTerminalListByLoginId(10001); + for (SaTerminalInfo ter : terminalList) { + System.out.println("登录index=" + ter.getIndex() + ", 设备type=" + ter.getDeviceType() + ", token=" + ter.getTokenValue() + ", 登录time=" + ter.getCreateTime()); + } + return SaResult.data(terminalList); + } + + // 测试注销 ---- http://localhost:8081/acc/logout @RequestMapping("logout") public SaResult logout() { diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java index d369c8b7..674d1f52 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java @@ -3,6 +3,8 @@ package com.pj.test; import cn.dev33.satoken.annotation.SaCheckHttpDigest; import cn.dev33.satoken.annotation.SaCheckSign; import cn.dev33.satoken.context.SaHolder; +import cn.dev33.satoken.session.SaSession; +import cn.dev33.satoken.session.SaTerminalInfo; import cn.dev33.satoken.spring.SpringMVCUtil; import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.parameter.SaLoginParameter; @@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Date; +import java.util.List; /** * 测试专用Controller @@ -25,10 +28,11 @@ public class TestController { // 测试登录 ---- http://localhost:8081/test/login @RequestMapping("login") - public SaResult login(@RequestParam(defaultValue = "10001") long id) { + public SaResult login(@RequestParam(defaultValue = "10001") long id, String dt) { StpUtil.login(id, new SaLoginParameter() .setIsConcurrent(true) .setIsShare(false) + .setDeviceType(dt) .setMaxLoginCount(4) .setMaxTryTimes(12) .setTerminalExtra("deviceSimpleTitle", "XiaoMi 15 Ultra") @@ -42,17 +46,23 @@ public class TestController { // 测试 浏览器访问: http://localhost:8081/test/test @RequestMapping("test") - @SaCheckSign(verifyParams = {"name", "age"}) public SaResult test() { System.out.println("------------进来了 " + SaFoxUtil.formatDate(new Date())); -// StpUtil.getLoginId(); -// StpUtil.getAnonTokenSession(); -// StpUtil.setTokenValue("xxx"); -// StpUtil.getSession().set("name", "zhang"); -// StpUtil.getSession().set("age", 18); -// SysUser user = new SysUser(10001, "lisi", 22); -// StpUtil.getSession().set("user", user); -// StpUtil.getTokenSession().set("user", user); + + + // 获取所有已登录的会话id + List sessionIdList = StpUtil.searchSessionId(null, 0, -1, false); + + for (String sessionId : sessionIdList) { + + // 根据会话id,查询对应的 SaSession 对象,此处一个 SaSession 对象即代表一个登录的账号 + SaSession session = StpUtil.getSessionBySessionId(sessionId); + + // 查询这个账号都在哪些设备登录了,依据上面的示例,账号A 的 SaTerminalInfo 数量是 3,账号B 的 SaTerminalInfo 数量是 2 + List terminalList = session.terminalListCopy(); + System.out.println("会话id:" + sessionId + ",共在 " + terminalList.size() + " 设备登录"); + } + // 返回 return SaResult.data(null); diff --git a/sa-token-doc/up/search-session.md b/sa-token-doc/up/search-session.md index 3f10751f..853d8765 100644 --- a/sa-token-doc/up/search-session.md +++ b/sa-token-doc/up/search-session.md @@ -1,22 +1,58 @@ # 会话查询 -尽管框架将大部分操作提供了简易的封装,但在一些特殊场景下,我们仍需要绕过框架,直达数据底层进行一些操作。 - -Sa-Token提供以下API助你直接操作会话列表: - - --- -## 具体API +### 1、单账号会话查询 + +使用 `StpUtil.getTerminalListByLoginId( loginId )` 可获取指定账号已登录终端列表信息,例如: + +``` java +public static void main(String[] args) { + System.out.println("账号 10001 登录设备信息:"); + List terminalList = StpUtil.getTerminalListByLoginId(10001); + for (SaTerminalInfo ter : terminalList) { + System.out.println("登录index=" + ter.getIndex() + ", 设备type=" + ter.getDeviceType() + ", token=" + ter.getTokenValue() + ", 登录time=" + ter.getCreateTime()); + } +} +``` + +控制台打印结果: + +``` txt +账号 10001 登录设备信息: +登录index=1, 设备type=PC, token=a8fbb46f-e043-459a-a875-0a2874911be8, 登录time=1742354951192 +登录index=2, 设备type=APP, token=882b6c9c-bdf9-4e8f-a42b-6e17d2fe0e34, 登录time=1742354960950 +登录index=3, 设备type=WEB, token=dacac78c-0983-4819-ab8b-07e7603597fc, 登录time=1742354962848 +``` + +一个 `SaTerminalInfo` 对象代表一个终端信息,其有如下字段: + +``` java +terminal.getIndex(); // 登录会话索引值 (该账号第几个登录的设备) +terminal.getDeviceType(); // 所属设备类型,例如:PC、WEB、HD、MOBILE、APP +terminal.getTokenValue(); // 此次登录的token值 +terminal.getCreateTime(); // 登录时间, 13位时间戳 +terminal.getDeviceId(); // 设备id, 设备唯一标识 +terminal.getExtra("key"); // 此次登录的额外自定义参数 +``` + +`Extra` 自定义参数可以在登录时通过如下方式指定: +``` java +StpUtil.login(10001, new SaLoginParameter().setTerminalExtra("key", "value")); +``` + + + +### 2、全部会话检索 ``` java // 查询所有已登录的 Token StpUtil.searchTokenValue(String keyword, int start, int size, boolean sortType); -// 查询所有账号 Session 会话 +// 查询所有 Account-Session 会话 StpUtil.searchSessionId(String keyword, int start, int size, boolean sortType); -// 查询所有令牌 Session 会话 +// 查询所有 Token-Session 会话 StpUtil.searchTokenSessionId(String keyword, int start, int size, boolean sortType); ``` @@ -36,7 +72,7 @@ for (String token : tokenList) { } ``` -#### 深入:`StpUtil.searchTokenValue` 和 `StpUtil.searchSessionId` 有哪些区别? +#### 深入:`StpUtil.searchTokenValue` 和 `StpUtil.searchSessionId` 的区别? - StpUtil.searchTokenValue 查询的是登录产生的所有 Token。 - StpUtil.searchSessionId 查询的是所有已登录账号会话id。 @@ -84,7 +120,7 @@ for (String sessionId : sessionIdList) { > [!WARNING| label:注意] -> 基于活动 Token 的统计方式会比实际情况略有延迟,如果需要精确统计实时在线用户信息建议采用 WebSocket。 +> 基于活跃 Token 的统计方式会比实际情况略有延迟,如果需要精确统计实时在线用户信息需要采用 WebSocket。 ---