使用 Sa-Token 实现不同的登录模式:单地登录、多地登录、同端互斥登录
一、需求分析
如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它可以手机电脑同时在线,但是不能在两个手机上同时登录一个账号。
同端互斥登录,指的就是:像腾讯QQ一样,在同一类型设备上只允许单地点登录,在不同类型设备上允许同时在线。
动态演示图:

Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。
Gitee 开源地址:https://gitee.com/dromara/sa-token
本文将介绍在 Sa-Token 中,如何实现以下登录策略:
- 单地登录:指一个账号同一时间只能在一个地方登录,新登录会挤掉旧登录,也可以叫:单端登录。
- 多地登录:指一个账号同一时间可以在不同地方登录,新登录会和旧登录共存,也可以叫:多端登录。
- 同端互斥登录:在同一类型设备上只允许单地点登录,在不同类型设备上允许同时在线,参考腾讯QQ的登录模式:手机和电脑可以同时在线,但不能两个手机同时在线。
与之对应的,注销策略也将分为以下几种:
- 单端注销:只在调用退出的一端注销。
- 全端注销:一端注销,全端下线。
- 同端注销:例如将所有手机端注销下线,PC端不受影响。
二、多地登录
此模式较为简单,Sa-Token 默认模式即为多地登录模式。
1、首先引入 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 即可。
2、在用户登录时将账号id写入会话中
@RestController
@RequestMapping("/user/")
public class UserController {
@RequestMapping("doLogin")
public SaResult doLogin(String username, String password) {
// 此处仅作示例模拟,真实项目需要从数据库中查询数据进行比对
if("zhang".equals(username) && "123456".equals(password)) {
StpUtil.login(10001);
return SaResult.ok("登录成功");
}
return SaResult.ok("登录失败");
}
}
启动类:
@SpringBootApplication
public class SaTokenDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SaTokenDemoApplication.class, args);
System.out.println("\n启动成功:Sa-Roken 配置如下:" + SaManager.getConfig());
}
}
如上代码,在多人登录同一账号时将不会对旧会话做任何处理,同一账号可以在多个地点任意登录,互不影响。
3、如果要全端注销,可以调用 logout 方法:
// 会话注销
@RequestMapping("logout")
public SaResult logout() {
StpUtil.logout();
return SaResult.ok("退出登录成功");
}
调用如上方法注销后,当前账号所有端将一起下线。
4、单端注销
如果要只注销一端,可将配置文件中 is-share 的值配置为 false
sa-token:
is-share: false
此配置项的含义为:在多人登录同一账号时,是否共用一个 Token。
- 为 true 时:所有登录共用一个 Token。
- 为 false 时:每次登录新建一个 Token。
此值为 false 后,每次登录都将返回不同的 Token,与之对应的,调用 StpUtil.logout() 也只会注销掉当前的 Token,其他端不受影响。
三、单地登录
单地登录的重点是需要改一下 yml 配置文件:
sa-token:
is-concurrent: false
is-concurrent 的含义为是否允许同一账号并发登录:
- 为 true 时:允许一起登录。
- 为 false 时:新登录挤掉旧登录。
其它代码与 [多地登录] 无异,当我们在两个浏览器分别登录同一账号时,旧会话再次访问系统将会得到如下提示:
{
"code": 401,
"msg": "Token 已被顶下线",
"data": null
}
在 单地登录 模式中,不存在注销策略的问题,因为同一时间内,一个账号最多在一个设备在线,只要调用注销,就必然是全端下线。
四、同端互斥登录
好了,终于轮到主角出场,同端互斥登录可以让我们像腾讯QQ一样,在同一类型设备上只允许单地点登录,在不同类型设备上允许同时在线。
那么在 Sa-Token 中如何做到同端互斥登录呢?
首先如 单地登录一样,在配置文件中,将 sa-token.is-concurrent 配置为false,然后调用登录等相关接口时声明设备标识即可:
1、指定设备标识登录
StpUtil.login(10001, "PC");
调用此方法登录后,同设备的会被顶下线(不同设备不受影响),再次访问系统时会抛出 NotLoginException 异常,场景值=-4
| 场景值 | 对应常量 | 含义说明 |
|---|---|---|
| -1 | NotLoginException.NOT_TOKEN | 未能从请求中读取到 Token |
| -2 | NotLoginException.INVALID_TOKEN | 已读取到 Token,但是 Token无效 |
| -3 | NotLoginException.TOKEN_TIMEOUT | 已读取到 Token,但是 Token已经过期 |
| -4 | NotLoginException.BE_REPLACED | 已读取到 Token,但是 Token 已被顶下线 |
| -5 | NotLoginException.KICK_OUT | 已读取到 Token,但是 Token 已被踢下线 |
如果第二个参数填写null或不填,代表将这个账号id所有在线端踢下线,被踢出者再次访问系统时会抛出 NotLoginException 异常,场景值=-5
2、查询当前登录的设备标识
StpUtil.getLoginDevice();
如果在登录时未指定设备类型值,调用此方法将返回默认值:default-device。
3、指定设备端类型下线
业务场景举例:在手机端控制PC端下线(手机端本身不受影响)
StpUtil.logout(10001, "PC");
4、全端下线
在调用 logout 方法时,不填写具体的设备端类型,将默认控制所有端一起下线。
StpUtil.logout(10001);
以上就是 Sa-Token 框架在处理登录问题时的各种方案,可以看出不管是简单的多地登录还是复杂的同端互斥登录,在 Sa-Token 都有完善的解决方案。
参考资料
- Sa-Token 文档:https://sa-token.cc
- Gitee 仓库地址:https://gitee.com/dromara/sa-token
- GitHub 仓库地址:https://github.com/dromara/sa-token
使用 Sa-Token 实现不同的登录模式:单地登录、多地登录、同端互斥登录的更多相关文章
- struts2中token防止重复提交表单
struts2中token防止重复提交表单 >>>>>>>>>>>>>>>>>>>&g ...
- Struts(二十七):使用token或tokenSession防止表单重复提交
什么是表单重复提交 表单重复提交包括以下几种情况: 前提:不刷新表单页面 1.多次点击“提交”按钮后,重复提交了多次: 2.已经提交成功之后,按“回退”按钮之后,在点击“提交”按钮后,提交成功: 3. ...
- Struts2 token禁止重复提交表单
如果服务器响应慢的情况下,用户会重复提交多个表单,这时候有两种设计思想: 1.在客户端使用JS技术,禁止客户重复提交表单.但是这样会使一些不使用浏览器方式登陆的人比如使用底层通信来攻击你的服务器 2. ...
- 利用创建的sa token来创建kubectl的config文件
1.第一步 创建一sa,并授予需要的一个权限(需要授予的权限) 2.第二步 取步骤1中的sa的 secret的token文件并进行base64解码 echo "$TOKEN&quo ...
- 使用electron将单页面vue webapp 打包成 PC端应用
在看张鑫旭博客得时候看到了electron这个东西,来了兴趣,就按照上面写的将已经做好得vue项目拿来试了试,出乎意料得顺利 electron简单说下electron,就是把 chrome内核和你的项 ...
- 从零开始学YC-Framework之鉴权
一.YC-Framework鉴权是基于哪一个开源框架做的? YC-Framework鉴权主要基于Dromara开源社区组织下的Sa-Token. 1.什么是Sa-Token? Sa-Token是一个轻 ...
- 我所理解的Restful API最佳实践
一直在公司负责API数据接口的开发,期间也遇到了不小的坑,本篇博客算是做一个小小的记录. 1. 不要纠结于无意义的规范 在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软 ...
- 我所认为的RESTful API最佳实践
我所认为的RESTful API最佳实践 不要纠结于无意义的规范 在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软件架构风格,过度纠结如何遵守规范只是徒增烦恼,也违背了使用它 ...
- sa-token v1.9.0 版本已发布,带来激动人心新特性:同端互斥登录
sa-token是什么? sa-token是一个JavaWeb轻量级权限认证框架, 官网首页:http://sa-token.dev33.cn/ 如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它 ...
- 单点登录SSO:概述与示例
目录 概述 演示一:零改造实施单点登录 演示二: 单点注销 演示三:集成AD认证 演示四:客户端单点登录 演示五:移动端单点登录 单点登录SSO概述 本系列将由浅入深的,带大家掌握最新单点登录SSO方 ...
随机推荐
- keycloak~时间不正确的问题
首先我们应该知道,写到数据库里的时间,主要和你的mysql时区system_time_zone有关,而把mysql里的数据取出来,以json形式响应到浏览器上,这个时间会经过反序列化的过程,这时时间和 ...
- 亿级Web系统负载均衡几种实现方式
负载均衡(Load Balance)是集群技术(Cluster)的一种应用技术.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是Web负载均衡.根据实现的原理 ...
- Linux(四)软件包管理
软件包管理 1 RPM 简介 RPM(RedHat Package Manager),是红帽系linux操作系统的软件包管理工具,类似于windows中的setup.exe能够进行软件包的更新.卸载. ...
- 频繁设置CGroup触发linux内核bug导致CGroup running task不调度
1. 说明 1> 本篇是实际工作中linux上碰到的一个问题,一个使用了CGroup的进程处于R状态但不执行,也不退出,还不能kill,经过深入挖掘才发现是Cgroup的内核bug 2>发 ...
- APISIX 是怎么保护用户的敏感数据不被泄露的?
本文以 APISIX 作为例子,为大家介绍了如何借助 Global Data Encryption 功能来保护敏感数据,确保不会有任何敏感数据进行明文存储,这样即使 etcd 中所有存储的数据都被盗取 ...
- 考前必备fa宝——对拍
2022.11.24:晚上zxs学长发来了他的博客,所以我仿照写一篇. https://www.cnblogs.com/Dita/p/duipai.html 对拍 对拍这个东西,就是可以比较两份代码跑 ...
- Eclipse 没有创建 Maven 项目入口的原因
试错过程 软件下载错了 我首先参考了 Eclipse历史版本下载和选择对应的java版本 这篇文章,发现 Eclipse 2020-06 的版本以后就不支持 JDK 8 了. 我想要下载 Oxygen ...
- .NET 6学习笔记(8)生成自签证书
上一篇我们通过导出IIS Express的自签证书,供ASP.NET Core程序启用HTTPS.本篇我们讨论如何生成自签证书.自签证书的生成,有多种方式.比如OpenSSL或PowerShell都可 ...
- 使用vite的创建vue项目
首先也是打开项目文件目录 在标签处快速打上cmd即可打开cmd窗口 然后按照顶部图进行操作即可完成 安装完成的样子如下图 紧接着输入 npm run dev 将Local 的IP复制到浏览器打开,出现 ...
- Rocky 9 Linux 平台 vim 9.0 源码包编译安装踩坑记录
目录 vim 9.0 部署准备环境 vim 9.0 源码包正式部署 vim 9.0 初体验 plug-vim 安装插件 在上一篇 <vim入门实战> 篇,我并没有介绍 Linux 平台源码 ...