zoukankan      html  css  js  c++  java
  • 一个登录功能也能玩出这么多花样?sa-token带你轻松搞定多地登录、单地登录、同端互斥登录

    需求场景

    说起登录,你可能会不屑一顾,还有比这更简单的功能吗?

    获取一下用户提交参数 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("
    启动成功: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有一个全面的了解

    如果觉得文章写得不错还请大家不要吝惜为文章点个赞,您的支持是我更新的最大动力!

    最后附上项目链接:





  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/shengzhang/p/14282300.html
Copyright © 2011-2022 走看看