Sa-Token不同模式实现单地登录 多地登录 同端互斥登录

 更新时间:2023年07月18日 10:42:49   作者:省长[机智]  
这篇文章主要为大家介绍了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

场景值对应常量含义说明
-1NotLoginException.NOT_TOKEN未能从请求中读取到 Token
-2NotLoginException.INVALID_TOKEN已读取到 Token,但是 Token无效
-3NotLoginException.TOKEN_TIMEOUT已读取到 Token,但是 Token已经过期
-4NotLoginException.BE_REPLACED已读取到 Token,但是 Token 已被顶下线
-5NotLoginException.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不同模式实现单地登录 多地登录 同端互斥登录的详细内容,更多关于Sa-Token登录模式的资料请关注脚本之家其它相关文章!

相关文章

  • Spring循环依赖的解决方法详解

    Spring循环依赖的解决方法详解

    Spring的解决循环依赖是有前置条件的,要解决循环依赖我们首先要了解Spring Bean对象的创建过程和依赖注入的方式。依赖注入方式,我之前的博客有所分享,大家可以在看本篇文章之前进行一下小小的回顾
    2022-08-08
  • java实现顺序结构线性列表的函数代码

    java实现顺序结构线性列表的函数代码

    java实现顺序结构线性列表的函数代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • IDEA配置使用Maven Helper插件的方法(详细配置)

    IDEA配置使用Maven Helper插件的方法(详细配置)

    这篇文章主要介绍了Maven Helper插件IDEA配置使用(详细配置),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 解决IDEA安装插件搜索不到插件的问题

    解决IDEA安装插件搜索不到插件的问题

    这篇文章主要介绍了解决IDEA安装插件搜索不到插件的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • SpringBoot实现ORM操作MySQL的几种方法

    SpringBoot实现ORM操作MySQL的几种方法

    本文主要介绍了SpringBoot实现ORM操作MySQL的几种方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 利用Java实现和可被K整除的子数组完整实例

    利用Java实现和可被K整除的子数组完整实例

    这篇文章主要给大家介绍了关于利用Java实现和可被K整除的子数组的相关资料,这道题来自力扣,通过学习这道题的解题思路以及代码对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • 抽象类使用Jackson序列化问题

    抽象类使用Jackson序列化问题

    这篇文章主要介绍了抽象类使用Jackson序列化问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • AJAX中Get请求报错404的原因以及解决办法

    AJAX中Get请求报错404的原因以及解决办法

    刚学习一门技术时总会踩一些坑,下面这篇文章主要给大家介绍了关于AJAX中Get请求报错404的原因及解决办法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • Java使用Collections工具类对List集合进行排序

    Java使用Collections工具类对List集合进行排序

    这篇文章主要介绍了Java使用Collections工具类对List集合进行排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • java中Hashtable和HashMap的区别分析

    java中Hashtable和HashMap的区别分析

    java中Hashtable和HashMap的区别分析,需要的朋友可以参考一下
    2013-04-04

最新评论