服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java使用Sa-Token框架完成踢人下线功能

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

2023-05-11 01:05未知服务器之家 Java教程

目录 一、需求 二、踢人下线 API 一览 三、根据账号踢人下线 四、根据 Token 踢人下线 参考资料 一、需求 在企业级项目中,踢人下线是一个很常见的需求,如果要设计比较完善的话,至少需要以下功能点: 可以根据用户 userId 踢出

目录
  • 一、需求
  • 二、踢人下线 API 一览
  • 三、根据账号踢人下线
  • 四、根据 Token 踢人下线
  • 参考资料

一、需求

在企业级项目中,踢人下线是一个很常见的需求,如果要设计比较完善的话,至少需要以下功能点:

  • 可以根据用户 userId 踢出指定会话,对方再次访问系统会被提示:您已被踢下线,请重新登录。
  • 可以查询出一个账号共在几个设备端登录,并返回其对应的 Token 凭证,以便后续操作。
  • 可以只踢出一个账号某一个端的会话,其他端不受影响。例如在某电商APP上可以看到当前账号共在几个手机上登录,并注销指定端的会话,当前端不受影响。

手动从零开始设计满足需求的会话架构,还是需要一定的代码量的。本篇将介绍如何使用 Sa-Token 方便的完成上述需求,Sa-Token 框架对踢人下线做了较为完整的封装,我们可以使用极少的代码就完成踢人下线功能。

Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。Gitee 开源地址:gitee.com/dromara/sa-token

首先在项目中引入 Sa-Token 依赖:

<!-- Sa-Token 权限认证 -->
<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 为我们提供的与踢人下线有关的API。

强制注销:

StpUtil.logout(10001);                    // 强制指定账号注销下线 
StpUtil.logout(10001, "PC");              // 强制指定账号指定端注销下线 
StpUtil.logoutByTokenValue("token");      // 强制指定 Token 注销下线 

踢人下线:

StpUtil.kickout(10001);                    // 将指定账号踢下线 
StpUtil.kickout(10001, "PC");              // 将指定账号指定端踢下线
StpUtil.kickoutByTokenValue("token");      // 将指定 Token 踢下线

强制注销 和 踢人下线 的区别在于:

  • 强制注销等价于对方主动调用了注销方法,再次访问会提示:Token无效。
  • 踢人下线不会清除Token信息,而是将其打上特定标记,再次访问会提示:Token已被踢下线。

动态图演示:

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

运行代码,分别用三个独立的浏览器测试登录:

// 使用浏览器 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

之所以使用三个独立的浏览器来测试,是为了避免会话的相互覆盖,造成逻辑不可控。访问成功的话,服务端的返回信息会类似如下:

{
	"code": 200,
	"msg": "登录成功,Token 凭证为:f53ac098-aed4-4de2-9223-8c3f1dab656d",
	"data": null
}

然后使用三个浏览器分别访问登录验证接口:http://localhost:8081/kick/checkLogin复制代码

返回信息如下:

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

现在开始测试踢人下线,使用任意浏览器访问:http://localhost:8081/kick/kickout?userId=10002复制代码

返回信息:

{
	"code": 200,
	"msg": "将账号 10002 踢下线成功",
	"data": null
}

账号 10002 将被踢下线成功,现在我们再使用浏览器2 测试一下 10002 是否仍然在线:

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

可以看到,10002会话已失效,无法通过登录校验。

四、根据 Token 踢人下线

业务场景举例:我要在APP上查看我的账号共在几个设备登录,并且将除我之外的设备全部踢下线。

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

sa-token: 
    is-share: false

is-share 的含义是:在多人登录同一账号时,是否共用同一个 Token:

  • 此值为 true 时,所有登录共用一个Token。
  • 此值为 false 时,每次登录新建一个Token。

在以上 KickController 的基础上,继续添加接口:

/**
 * 测试踢人下线
 */
@RestController
@RequestMapping("/kick/")
public class KickController {
	// 其他代码...
	// 以下是需要新添加的代码
    // 查询我的账号已经在几个设备登录  ---- http://localhost:8081/kick/tokenList
    @RequestMapping("tokenList")
    public SaResult tokenList() {
        long currUserId = StpUtil.getLoginIdAsLong();
        List<String> tokenList = StpUtil.getTokenValueListByLoginId(currUserId);
        return SaResult.data(tokenList);
    }
    // 根据 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数据一下),分别从三个独立的浏览器测试访问:http://localhost:8081/kick/doLogin?userId=10001复制代码

返回如下:

{
	"code": 200,
	"msg": "登录成功,Token 凭证为:450b8b73-f52d-4496-b67e-bdd579c8708a",
	"data": null
}

仔细观察三个浏览器返回的信息,虽然三个浏览器都是登录账号 10001,但是每次返回的 Token 凭证都是不一样的。

现在查询一下当前账号一共在几个设备完成了登录: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"
	]
}

现在选一个 Token,将其踢下线:http://localhost:8081/kick/kickoutToken?token=d73c1bc5-d04f-4dc2-81ee-42c9438f9d78复制代码

返回信息如下:

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

然后在对应的浏览器,验证一下登录状态:http://localhost:8081/kick/checkLogin复制代码

返回如下:

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

可以看到,该设备登录的会话已被踢下线。那么同账号的其他设备有没有受到影响呢,我们从其他浏览器验证一下:http://localhost:8081/kick/checkLogin复制代码

返回如下:

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

可以看到,只有踢出的 Token 被强制下线了,其他端并没有受到影响。

参考资料

  • Sa-Token 文档:sa-token.cc
  • Gitee 仓库地址:gitee.com/dromara/sa-token
  • GitHub 仓库地址:github.com/dromara/sa-token
原文地址:https://juejin.cn/post/7231015615254921272

延伸 · 阅读

精彩推荐
  • Java教程Java List 用法实例详解

    Java List 用法实例详解

    这篇文章主要介绍了Java List 用法实例详解的相关资料,需要的朋友可以参考下...

    qq_372670157322020-12-29
  • Java教程spring mvc4中相关注解的详细讲解教程

    spring mvc4中相关注解的详细讲解教程

    这篇文章主要给大家介绍了关于spring mvc4中相关注解的相关资料,其中详细介绍了关于@Controller、@RequestMapping、@RathVariable、@RequestParam及@RequestBody等等注解的...

    chen20133792020-11-23
  • Java教程关于synchronized有趣的同步问题

    关于synchronized有趣的同步问题

    今天小编就为大家分享一篇关于关于synchronized有趣的同步问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编...

    李灿辉7042021-06-30
  • Java教程Springboot使用influxDB时序数据库的实现

    Springboot使用influxDB时序数据库的实现

    项目中需要存放大量设备日志,且需要对其进行简单的数据分析,信息提取工作,所以本文就介绍一下Springboot使用influxDB时序数据库,感兴趣的可以了解一下...

    从此寂静无11772021-11-04
  • Java教程java面试题——详解HashMap和Hashtable 的区别

    java面试题——详解HashMap和Hashtable 的区别

    本篇文章主要介绍了java中HashMap和Hashtable的区别,具有一定的参考价值,有需要的可以了解一下。...

    无限大5982020-07-07
  • Java教程Java数据结构之有效队列定义与用法示例

    Java数据结构之有效队列定义与用法示例

    这篇文章主要介绍了Java数据结构之有效队列定义与用法,结合实例形式分析了java有效队列的数据插入、删除、判断、计算等相关操作技巧,需要的朋友可以参...

    CharlinGod11812021-01-24
  • Java教程Java 递归查询部门树形结构数据的实践

    Java 递归查询部门树形结构数据的实践

    本文主要介绍了Java 递归查询部门树形结构数据的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    哥的冷酷,你模仿不来7432022-01-12
  • Java教程MyBatis的逆向工程详解

    MyBatis的逆向工程详解

    这篇文章主要介绍了MyBatis的逆向工程详解,详细的介绍了逆行工程的概念和实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    source10482021-05-23