共计 2960 个字符,预计需要花费 8 分钟才能阅读完成。
需要场景
说起登录,你可能会等闲视之,还有比这更简略的性能吗?
获取一下用户提交参数 username
+ password
和数据库中一比对,有记录返回[登录胜利],无记录返回[用户名或明码谬误]
什么,就这?
当你纯熟的打包、部署、启动我的项目开始了一天的摸鱼之后,产品经理开始坐不住了
“小顺子啊,你看咱们的 APP 登录能不能加一个性能,就是那种 …… 那个 …… 一个用户登录之后,能把上一个登录的主动挤下线”
此时的你陷入了深思,怎么让他在登录之后,把上一个登录者的会话给挤下线呢?
难道说要在每次登录之后循环一遍Session 列表
,找到与此用户同账号的会话将其登记,聪慧如你马上想到了这种计划将会给服务器带来微小的性能压力!
那怎么办?难道要建个 Map 以 userId 做 key
、Session 做 value
,建设起映射关系,而后手动取出Session
做上标记[已被挤下线]?
说干就干,当你撸起袖子,噼里啪啦敲好上述逻辑之后,而后测试、打包、部署、上传零打碎敲,又开始了一天的摸鱼 ……
然而你还是低估了产品经理的脑洞能力
“小顺子,你看你写的性能有点小问题啊,我每次一登录,就会把其它登录地给挤掉线啊。”
此时的你下意识反驳到: “ 有什么问题?这难道不就是你想要的成果吗?”
“en…. 就是 …. 咱们能不能这样,我在手机上登录,能不能只把别的手机上给挤下线,然而我电脑上曾经登录的不受影响”
“挤掉必定是全副挤掉啊,怎么可能只留下你电脑端不挤掉呢?你要的性能不可能做到”
只见此时产品经理嘴角微微一笑,放出了大招:
“那人家腾讯 QQ 是怎么做到的呢?”
一句话暴击 99999+,登时你理屈词穷,是呀,腾讯 QQ
怎么做到这种性能的呢?一个 QQ 号能够在手机和电脑上同时在线,然而却不能两个手机同时在线
难道说在登录时再记录时每次登录的设施标识?循环检测登录列表的设施名称,同设施挤下线,不同设施放弃登录?
产品经理冲上咖啡,带着胜利的微笑来到了房间,只留下一脸笑容的你,左思右想着实现计划……
正题
好了,说了这么多,上面进入明天的主题————sa-token,一个能够让你轻松解决各种登录问题的权限认证框架!
如上述场景所言,你遇到的问题不过是三个典型的登录模型:多地登录、单地登录、同端互斥登录
- 多地登录:指同一账号能够在任意地点同时登录,互不影响
- 单地登录:在同一时间一个账号只能在一个地点登录,新登录会挤掉旧登录者
- 同端互斥登录:在同一类型设施上只容许单地点登录,在不同类型设施上容许同时在线
接下来让咱们看看应用 sa-token
是如何轻松解决这三种登录问题的
多地登录
此模式较为简单,sa-token
默认模式即为多地登录模式
- 首先增加
pom.xml
框架
<!-- sa-token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.12.1</version>
</dependency>
- 在用户登录时将账号 id 写入会话中
@RestController
@RequestMapping("user")
public class UserController {@RequestMapping("doLogin")
public String doLogin(String username, String password) {
// 此处仅作示例模仿,实在我的项目须要从数据库中查问数据进行比对
if("zhang".equals(username) && "123456".equals(password)) {StpUtil.setLoginId(10001);
return "登录胜利";
}
return "登录失败";
}
}
- 新建启动类启动
@SpringBootApplication
public class SaTokenDemoApplication {public static void main(String[] args) {SpringApplication.run(SaTokenDemoApplication.class, args);
System.out.println("\n 启动胜利:sa-token 配置如下:" + SaTokenManager.getConfig());
}
}
至此,咱们曾经实现了多地点登录的全副代码,上述代码在多人登录同一账号时将不会对旧会话做任何解决,同一账号能够在多个地点任意登录,互不影响
单地登录
单地登录
与多地登录
惟一的差别就是, 须要改一下 yml 配置文件
spring:
# sa-token 配置
sa-token:
allow-concurrent-login: false
配置项 allow-concurrent-login
的含意为:是否容许同一账号并发登录 (此值为 true 时容许一起登录, 为 false 时新登录挤掉旧登录)
其它代码与 [多地登录] 无异,当咱们在两个浏览器别离登录同一账号时,旧会话再次拜访零碎将会失去如下提醒:
{
"code": 401,
"msg": "token 已被顶下线",
"data": null,
"dataCount": null
}
同端互斥登录
好了,终于到了最终难题,同端互斥登录能够让咱们像 腾讯 QQ
一样,在同一类型设施上只容许单地点登录,在不同类型设施上容许同时在线
那么在 sa-token
中如何做到同端互斥登录呢?
首先如 单地登录
一样,在配置文件中,将 allowConcurrentLogin
配置为false
,而后调用登录等相干接口时申明设施标识即可:
指定设施标识登录
StpUtil.setLoginId(10001, "PC");
调用此办法登录后,同设施的会被顶下线(不同设施不受影响),再次拜访零碎时会抛出 NotLoginException
异样,场景值 =-4
指定设施标识强制登记(踢人下线)
StpUtil.logoutByLoginId(10001, "PC");
如果第二个参数填写 null 或不填,代表将这个账号 id 所有在线端踢下线,被踢出者再次拜访零碎时会抛出 NotLoginException
异样,场景值 =-5
查问以后登录的设施标识
StpUtil.getLoginDevice();
结尾
以上就是 sa-token
框架在解决登录问题时的各种技巧,能够看出不论是简略的 多地登录
还是简单的 同端互斥登录
,在sa-token
都有实现的解决方案
sa-token
是近期开源的国产优良权限认证框架,除了各种登录认证,sa-token
还能够轻松解决我的项目中的各种权限认证问题,
比方:踢人下线、主动续签、身份长期切换等常见业务均能够一行代码调用实现,接下来的文章我会逐个介绍这些个性,让大家对 sa-token
有一个全面的理解
如果感觉文章写得不错还请大家不要吝惜为文章点个赞,您的反对是我更新的最大能源!
最初附上我的项目链接:
- 官网文档:http://sa-token.dev33.cn/
- Gitee 开源地址: https://gitee.com/sz6/sa-token
- GitHub 开源地址: https://github.com/click33/sa-token