关于java:一个登录功能也能玩出这么多花样satoken带你轻松搞定多地登录单地登录同端互斥登录

4次阅读

共计 2960 个字符,预计需要花费 8 分钟才能阅读完成。

需要场景

说起登录,你可能会等闲视之,还有比这更简略的性能吗?

获取一下用户提交参数 username + password 和数据库中一比对,有记录返回[登录胜利],无记录返回[用户名或明码谬误]

什么,就这?

当你纯熟的打包、部署、启动我的项目开始了一天的摸鱼之后,产品经理开始坐不住了

“小顺子啊,你看咱们的 APP 登录能不能加一个性能,就是那种 …… 那个 …… 一个用户登录之后,能把上一个登录的主动挤下线”

此时的你陷入了深思,怎么让他在登录之后,把上一个登录者的会话给挤下线呢?

难道说要在每次登录之后循环一遍Session 列表,找到与此用户同账号的会话将其登记,聪慧如你马上想到了这种计划将会给服务器带来微小的性能压力!

那怎么办?难道要建个 Map 以 userId 做 keySession 做 value,建设起映射关系,而后手动取出Session 做上标记[已被挤下线]?

说干就干,当你撸起袖子,噼里啪啦敲好上述逻辑之后,而后测试、打包、部署、上传零打碎敲,又开始了一天的摸鱼 ……

然而你还是低估了产品经理的脑洞能力

“小顺子,你看你写的性能有点小问题啊,我每次一登录,就会把其它登录地给挤掉线啊。”

此时的你下意识反驳到: “ 有什么问题?这难道不就是你想要的成果吗?”

“en…. 就是 …. 咱们能不能这样,我在手机上登录,能不能只把别的手机上给挤下线,然而我电脑上曾经登录的不受影响”

“挤掉必定是全副挤掉啊,怎么可能只留下你电脑端不挤掉呢?你要的性能不可能做到”

只见此时产品经理嘴角微微一笑,放出了大招:

“那人家腾讯 QQ 是怎么做到的呢?”

一句话暴击 99999+,登时你理屈词穷,是呀,腾讯 QQ怎么做到这种性能的呢?一个 QQ 号能够在手机和电脑上同时在线,然而却不能两个手机同时在线

难道说在登录时再记录时每次登录的设施标识?循环检测登录列表的设施名称,同设施挤下线,不同设施放弃登录?

产品经理冲上咖啡,带着胜利的微笑来到了房间,只留下一脸笑容的你,左思右想着实现计划……


正题

好了,说了这么多,上面进入明天的主题————sa-token,一个能够让你轻松解决各种登录问题的权限认证框架!

如上述场景所言,你遇到的问题不过是三个典型的登录模型:多地登录、单地登录、同端互斥登录

  • 多地登录:指同一账号能够在任意地点同时登录,互不影响
  • 单地登录:在同一时间一个账号只能在一个地点登录,新登录会挤掉旧登录者
  • 同端互斥登录:在同一类型设施上只容许单地点登录,在不同类型设施上容许同时在线

接下来让咱们看看应用 sa-token 是如何轻松解决这三种登录问题的

多地登录

此模式较为简单,sa-token默认模式即为多地登录模式

  1. 首先增加 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>
  1. 在用户登录时将账号 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 "登录失败";
    }
}
  1. 新建启动类启动
@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
正文完
 0