栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot集成Sa-Token进行鉴权

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot集成Sa-Token进行鉴权

Sa-Token

官方文档

1 添加依赖

    cn.dev33
    sa-token-spring-boot-starter
    1.28.0

2 配置文件
server:
    # 端口
    port: 8081

# Sa-Token配置
sa-token: 
    # token名称 (同时也是cookie名称)
    token-name: satoken
    # token有效期,单位s 默认30天, -1代表永不过期 
    timeout: 2592000
    # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
    activity-timeout: -1
    # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) 
    is-concurrent: true
    # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) 
    is-share: false
    # token风格
    token-style: uuid
    # 是否输出操作日志 
    is-log: false

3 登录认证 3.1 登录与注销
// 标记当前会话登录的账号id 
// 建议的参数类型:long | int | String, 不可以传入复杂类型,如:User、Admin等等
StpUtil.login(Object id);     

// 当前会话注销登录
StpUtil.logout();

// 获取当前会话是否已经登录,返回true=已登录,false=未登录
StpUtil.isLogin();

// 检验当前会话是否已经登录, 如果未登录,则抛出异常:`NotLoginException`
StpUtil.checkLogin();
3.2 会话查询
// 获取当前会话账号id, 如果未登录,则抛出异常:`NotLoginException`
StpUtil.getLoginId();

// 类似查询API还有:
StpUtil.getLoginIdAsString();    // 获取当前会话账号id, 并转化为`String`类型
StpUtil.getLoginIdAsInt();       // 获取当前会话账号id, 并转化为`int`类型
StpUtil.getLoginIdAsLong();      // 获取当前会话账号id, 并转化为`long`类型

// ---------- 指定未登录情形下返回的默认值 ----------

// 获取当前会话账号id, 如果未登录,则返回null 
StpUtil.getLoginIdDefaultNull();

// 获取当前会话账号id, 如果未登录,则返回默认值 (`defaultValue`可以为任意类型)
StpUtil.getLoginId(T defaultValue);

// 获取指定token对应的账号id,如果未登录,则返回 null
StpUtil.getLoginIdByToken(String tokenValue);

// 获取当前`StpLogic`的token名称
StpUtil.getTokenName();

// 获取当前会话的token值
StpUtil.getTokenValue();

// 获取当前会话的token信息参数
StpUtil.getTokenInfo();

4 权限认证 4.1 设置权限码和角色
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.stp.StpInterface;


@Component
public class StpInterfaceImpl implements StpInterface {

    
    @Override
    public List getPermissionList(Object loginId, String loginType) {
        // 模拟权限码
        List list = new ArrayList();    
        list.add("101");
        list.add("user-add");
        list.add("user-delete");
        list.add("user-update");
        list.add("user-get");
        list.add("article-get");
        return list;
    }

    
    @Override
    public List getRoleList(Object loginId, String loginType) {
        // 模拟角色
        List list = new ArrayList();    
        list.add("admin");
        list.add("super-admin");
        return list;
    }

}
4.2 权限认证
// 判断:当前账号是否含有指定权限, 返回true或false
StpUtil.hasPermission("user-update");        

// 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException 
StpUtil.checkPermission("user-update");        

// 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过]
StpUtil.checkPermissionAnd("user-update", "user-delete");        

// 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
StpUtil.checkPermissionOr("user-update", "user-delete");        
4.3 角色认证
// 判断:当前账号是否拥有指定角色, 返回true或false
StpUtil.hasRole("super-admin");        

// 校验:当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
StpUtil.checkRole("super-admin");        

// 校验:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
StpUtil.checkRoleAnd("super-admin", "shop-admin");        

// 校验:当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可] 
StpUtil.checkRoleOr("super-admin", "shop-admin");        
4.4 权限通配符

Sa-Token允许你根据通配符指定泛权限,例如当一个账号拥有user*的权限时,user-add、user-delete、user-update都将匹配通过 。

// 当拥有 user* 权限时
StpUtil.hasPermission("user-add");        // true
StpUtil.hasPermission("user-update");     // true
StpUtil.hasPermission("art-add");         // false

// 当拥有 *-delete 权限时
StpUtil.hasPermission("user-add");        // false
StpUtil.hasPermission("user-delete");     // true
StpUtil.hasPermission("art-delete");      // true

// 当拥有 *.js 权限时
StpUtil.hasPermission("index.js");        // true
StpUtil.hasPermission("index.css");       // false
StpUtil.hasPermission("index.html");      // false

上帝权限:当一个账号拥有 "*" 权限时,他可以验证通过任何权限码 (角色认证同理) 。

5 踢人下线 5.1 强制注销
StpUtil.logout(10001);                    // 强制指定账号注销下线 
StpUtil.logout(10001, "PC");              // 强制指定账号指定端注销下线 
StpUtil.logoutByTokenValue("token");      // 强制指定 Token 注销下线 
5.2 踢人下线
StpUtil.kickout(10001);                    // 将指定账号踢下线 
StpUtil.kickout(10001, "PC");              // 将指定账号指定端踢下线
StpUtil.kickoutByTokenValue("token");      // 将指定 Token 踢下线

强制注销 和 踢人下线 的区别在于:

  • 强制注销等价于对方主动调用了注销方法,再次访问会提示:Token无效。
  • 踢人下线不会清除Token信息,而是将其打上特定标记,再次访问会提示:Token已被踢下线。
5.3 账号封禁

对于违规账号,有时候我们仅仅将其踢下线还是远远不够的,我们还需要对其进行账号封禁防止其再次登录 。

// 封禁指定账号 
// 参数一:账号id
// 参数二:封禁时长,单位:秒  (86400秒=1天,此值为-1时,代表永久封禁)
StpUtil.disable(10001, 86400); 

// 获取指定账号是否已被封禁 (true=已被封禁, false=未被封禁) 
StpUtil.isDisable(10001); 

// 获取指定账号剩余封禁时间,单位:秒
StpUtil.getDisableTime(10001); 

// 解除封禁
StpUtil.untieDisable(10001); 

注意

对于正在登录的账号,对其账号封禁时并不会使其立刻注销
如果需要将其封禁后立即掉线,可采取先踢再封禁的策略,例如:

// 先踢下线
StpUtil.kickout(10001); 
// 再封禁账号 封一天1
StpUtil.disable(10001, 86400); 
6 注解式鉴权

注解鉴权 —— 优雅的将鉴权与业务代码分离!

  • @SaCheckLogin: 登录认证 —— 只有登录之后才能进入该方法
  • @SaCheckRole("admin"): 角色认证 —— 必须具有指定角色标识才能进入该方法
  • @SaCheckPermission("user:add"): 权限认证 —— 必须具有指定权限才能进入该方法
  • @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法
  • @SaCheckBasic: HttpBasic认证 —— 只有通过 Basic 认证后才能进入该方法

Sa-Token使用全局拦截器完成注解鉴权功能,为了不为项目带来不必要的性能负担,拦截器默认处于关闭状态
因此,为了使用注解鉴权,你必须手动将Sa-Token的全局拦截器注册到你项目中。

6.1 注册拦截器

注:注册拦截器方式的注解鉴权只能加在controller层。

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注册Sa-Token的注解拦截器,打开注解式鉴权功能 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关)
        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns(" );

// 根据 path 路由排除匹配 
SaRouter.match(" );

// 根据请求类型匹配 
SaRouter.match(SaHttpMethod.GET).check(  );

// 根据一个 boolean 条件进行匹配 
SaRouter.match( StpUtil.isLogin() ).check(  );

// 根据一个返回 boolean 结果的lambda表达式匹配 
SaRouter.match( r -> StpUtil.isLogin() ).check(  );

// 多个条件一起使用 
SaRouter.match(SaHttpMethod.GET).match(" );

// 可以无限连缀下去 
SaRouter
    .match(SaHttpMethod.GET)
    .match("/admin*.js")
    .notMatch("*.css")
    // ....
    .check(  );
7.4 提前退出匹配链

使用 SaRouter.stop() 可以提前退出匹配链,例:

registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> {
    SaRouter.match(");
    SaRouter.match("/a).stop();
    SaRouter.match("/a);
});
// 执行 stop() 函数跳出 free 后继续执行下面的 match 匹配 
SaRouter.match(");

free() 的作用是:打开一个独立的作用域,使内部的 stop() 不再一次性跳出整个 Auth 函数,而是仅仅跳出当前 free 作用域。

8 Session会话

Session是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能,例如:

// 在登录时缓存user对象 
StpUtil.getSession().set("user", user);

// 然后我们就可以在任意处使用这个user对象
SysUser user = (SysUser) StpUtil.getSession().get("user")

在 Sa-Token 中,Session 分为三种,分别是:

  • User-Session: 指的是框架为每个 账号id 分配的 Session
  • Token-Session: 指的是框架为每个 token 分配的 Session
  • Custom-Session: 指的是以一个 特定的值 作为SessionId,来分配的 Session

有关User-Session与Token-Session的详细区别,请参考:Session模型详解

8.1 User-Session

有关账号Session的API如下:

// 获取当前账号id的Session (必须是登录后才能调用)
StpUtil.getSession();

// 获取当前账号id的Session, 并决定在Session尚未创建时,是否新建并返回
StpUtil.getSession(true);

// 获取账号id为10001的Session
StpUtil.getSessionByLoginId(10001);

// 获取账号id为10001的Session, 并决定在Session尚未创建时,是否新建并返回
StpUtil.getSessionByLoginId(10001, true);

// 获取SessionId为xxxx-xxxx的Session, 在Session尚未创建时, 返回null 
StpUtil.getSessionBySessionId("xxxx-xxxx");
8.2 Token-Session

有关令牌Session的API如下:

// 获取当前token的专属Session 
StpUtil.getTokenSession();

// 获取指定token的专属Session 
StpUtil.getTokenSessionByToken(token);

在未登录状态下是否可以获取Token-Session?这取决于你配置的tokenSessionCheckLogin值是否为false,详见:框架配置

8.3 自定义Session

自定义Session指的是以一个特定的值作为SessionId来分配的Session, 借助自定义Session,你可以为系统中的任意元素分配相应的session
例如以商品id作为key为每个商品分配一个Session,以便于缓存和商品相关的数据,其相关API如下:

// 查询指定key的Session是否存在
SaSessionCustomUtil.isExists("goods-10001");

// 获取指定key的Session,如果没有,则新建并返回
SaSessionCustomUtil.getSessionById("goods-10001");

// 获取指定key的Session,如果没有,第二个参数决定是否新建并返回  
SaSessionCustomUtil.getSessionById("goods-10001", false);   

// 删除指定key的Session
SaSessionCustomUtil.deleteSessionById("goods-10001");
8.4 Session相关操作
// 返回此Session的id 
session.getId();                          

// 返回此Session的创建时间 (时间戳) 
session.getCreateTime();                  

// 在Session上获取一个值 
session.getAttribute('name');             

// 在Session上获取一个值,并指定取不到值时返回的默认值
session.getAttribute('name', 'zhang');    

// 在Session上写入一个值 
session.setAttribute('name', 'zhang');    

// 在Session上移除一个值 
session.removeAttribute('name');          

// 清空此Session的所有值 
session.clearAttribute();                 

// 获取此Session是否含有指定key (返回true或false)
session.containsAttribute('name');        

// 获取此Session会话上所有key (返回Set)
session.attributeKeys();                  

// 返回此Session会话上的底层数据对象(如果更新map里的值,请调用session.update()方法避免产生脏数据)
session.getDataMap();                     

// 将这个Session从持久库更新一下
session.update();                         

// 注销此Session会话 (从持久库删除此Session)
session.logout();                         
8.5 类型转换API

由于Session存取值默认的类型都是Object,因此我们通常会写很多不必要类型转换代码
为了简化操作,Sa-Token自v1.15.0封装了存取值API的类型转换,你可以非常方便的调用以下方法:

// 写值 
session.set("name", "zhang"); 

// 写值 (只有在此key原本无值的时候才会写入)
session.setDefaultValue("name", "zhang");

// 取值
session.get("name");

// 取值 (指定默认值)
session.get("name", ""); 

// 取值 (转String类型)
session.getString("name"); 

// 取值 (转int类型)
session.getInt("age"); 

// 取值 (转long类型)
session.getLong("age"); 

// 取值 (转double类型)
session.getDouble("result"); 

// 取值 (转float类型)
session.getFloat("result"); 

// 取值 (指定转换类型)
session.getModel("key", Student.class); 

// 取值 (指定转换类型, 并指定值为Null时返回的默认值)
session.getModel("key", Student.class, ); 

// 是否含有某个key
session.has("key"); 
8.6 Sesion环境隔离说明

有同学经常会把 SaSession 与 HttpSession 进行混淆,例如:

@PostMapping("/resetPoints")
public void reset(HttpSession session) {
    // 在HttpSession上写入一个值 
    session.setAttribute("name", 66);
    // 在SaSession进行取值
    System.out.println(StpUtil.getSession().getAttribute("name"));    // 输出null
}

要点:

  1. SaSession 与 HttpSession 没有任何关系,在HttpSession上写入的值,在SaSession中无法取出。
  2. HttpSession并未被框架接管,在使用Sa-Token时,请在任何情况下均使用SaSession,不要使用HttpSession。
9 框架配置

框架配置

10 集成Redis

集成Redis

11 前后端分离

前后端分离

12 自定义Token风格 12.1 内置风格

Sa-Token默认的token生成策略是uuid风格,其模样类似于:623368f0-ae5e-4475-a53f-93e4225f16ae
如果你对这种风格不太感冒,还可以将token生成设置为其他风格

怎么设置呢?只需要在yml配置文件里设置 sa-token.token-style=风格类型 即可,其有多种取值:

// 1. token-style=uuid    —— uuid风格 (默认风格)
"623368f0-ae5e-4475-a53f-93e4225f16ae"

// 2. token-style=simple-uuid    —— 同上,uuid风格, 只不过去掉了中划线
"6fd4221395024b5f87edd34bc3258ee8"

// 3. token-style=random-32    —— 随机32位字符串
"qEjyPsEA1Bkc9dr8YP6okFr5umCZNR6W"

// 4. token-style=random-64    —— 随机64位字符串
"v4ueNLEpPwMtmOPMBtOOeIQsvP8z9gkMgIVibTUVjkrNrlfra5CGwQkViDjO8jcc"

// 5. token-style=random-128    —— 随机128位字符串
"nojYPmcEtrFEaN0Otpssa8I8jpk8FO53UcMZkCP9qyoHaDbKS6dxoRPky9c6QlftQ0pdzxRGXsKZmUSrPeZBOD6kJFfmfgiRyUmYWcj4WU4SSP2ilakWN1HYnIuX0Olj"

// 6. token-style=tik    —— tik风格
"gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__"
12.2 自定义token生成策略

如果觉着以上风格都不是你喜欢的类型,那么还可以自定义token生成策略,来定制化token生成风格

怎么做呢?只需要重写 SaStrategy 策略类的 createToken 算法即可

步骤:

1、在SaTokenConfigure配置类中添加代码:

@Configuration
public class SaTokenConfigure {
    
    @Autowired
    public void rewriteSaStrategy() {
        // 重写 Token 生成策略 
        SaStrategy.me.createToken = (loginId, loginType) -> {
            return SaFoxUtil.getRandomString(60);    // 随机60位长度字符串
        };
    }
}

2、再次调用 StpUtil.login(10001)方法进行登录,观察其生成的token样式:

gfuPSwZsnUhwgz08GTCH4wOgasWtc3odP4HLwXJ7NDGOximTvT4OlW19zeLH
13 自定义Token前缀

在某些系统中,前端提交token时会在前面加个固定的前缀,例如:

{
    "satoken": "Bearer xxxx-xxxx-xxxx-xxxx"
}

此时后端如果不做任何特殊处理,框架将会把Bearer视为token的一部分,无法正常读取token信息,导致鉴权失败

为此,我们需要在yml中添加如下配置:

sa-token: 
    # token前缀
    token-prefix: Bearer

此时 Sa-Token 便可在读取 Token 时裁剪掉 Bearer,成功获取xxxx-xxxx-xxxx-xxxx

注意:

  1. Token前缀 与 Token值 之间必须有一个空格。
  2. 一旦配置了 Token前缀,则前端提交token时,必须带有前缀,否则会导致框架无法读取token。
  3. 由于cookie中无法存储空格字符,也就意味配置token前缀后,cookie鉴权方式将会失效,此时只能将token提交到header里进行传输。
14 记住我模式 14.1 实现

在Sa-Token中实现记住我功能

Sa-Token的登录授权,默认就是[记住我]模式,为了实现[非记住我]模式, 你需要在登录时如下设置:

// 设置登录账号id为10001,第二个参数指定是否为[记住我],当此值为false后,关闭浏览器后再次打开需要重新登录
StpUtil.login(10001, false);
14.2 实现原理

cookie作为浏览器提供的默认会话跟踪机制,其生命周期有两种形式,分别是:

  • 临时cookie:有效期为本次会话,只要关闭浏览器窗口,cookie就会消失。
  • 永久cookie:有效期为一个具体的时间,在时间未到期之前,即使用户关闭了浏览器cookie也不会消失。

利用cookie的此特性,我们便可以轻松实现 [记住我] 模式:

  • 勾选 [记住我] 按钮时:调用StpUtil.login(10001, true),在浏览器写入一个永久cookie储存 Token,此时用户即使重启浏览器 Token 依然有效。
  • 不勾选 [记住我] 按钮时:调用StpUtil.login(10001, false),在浏览器写入一个临时cookie储存 Token,此时用户在重启浏览器后 Token 便会消失,导致会话失效。
14.3 前后台分离实现记住我

以经典跨端框架 uni-app 为例,我们可以使用如下方式达到同样的效果:

// 使用本地存储保存token,达到 [永久cookie] 的效果
uni.setStorageSync("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");

// 使用globalData保存token,达到 [临时cookie] 的效果
getApp().globalData.satoken = "xxxx-xxxx-xxxx-xxxx-xxx";

如果你决定在PC浏览器环境下进行前后台分离模式开发,那么更加简单:

// 使用 localStorage 保存token,达到 [永久cookie] 的效果
localStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");

// 使用 sessionStorage 保存token,达到 [临时cookie] 的效果
sessionStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");
14.4 登录时指定token有效期
// 示例1:
// 指定token有效期(单位: 秒),如下所示token七天有效
StpUtil.login(10001, new SaLoginModel().setTimeout(60 * 60 * 24 * 7));

// ----------------------- 示例2:所有参数
// `SaLoginModel`为登录参数Model,其有诸多参数决定登录时的各种逻辑,例如:
StpUtil.login(10001, new SaLoginModel()
            .setDevice("PC")                // 此次登录的客户端设备标识, 用于[同端互斥登录]时指定此次登录的设备名称
            .setIsLastingcookie(true)        // 是否为持久cookie(临时cookie在浏览器关闭时会自动删除,持久cookie在重新打开后依然存在)
            .setTimeout(60 * 60 * 24 * 7)    // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的timeout值)
            );
15 模拟他人&身份切换

点击了解

16 同端互斥登录

首先在配置文件中,将 isConcurrent 配置为false,然后调用登录等相关接口时声明设备标识即可:

  • 指定设备标识登录

    // 指定`账号id`和`设备标识`进行登录
    StpUtil.login(10001, "PC"); 
    

    调用此方法登录后,同设备的会被顶下线(不同设备不受影响),再次访问系统时会抛出 NotLoginException 异常,场景值=-4 。

  • 指定设备标识强制注销

    // 指定`账号id`和`设备标识`进行强制注销 
    StpUtil.logout(10001, "PC");  
    

    如果第二个参数填写null或不填,代表将这个账号id所有在线端强制注销,被踢出者再次访问系统时会抛出 NotLoginException 异常,场景值=-2 。

  • 查询当前登录的设备标

    // 返回当前token的登录设备
    StpUtil.getLoginDevice();    
    
  • Id反查Token

    // 获取指定loginId指定设备端的tokenValue 
    StpUtil.getTokenValueByLoginId(10001, "APP");    
    
17 二级认证

在某些敏感操作下,我们需要对已登录的会话进行二次验证

比如代码托管平台的仓库删除操作,尽管我们已经登录了账号,当我们点击 [删除] 按钮时,还是需要再次输入一遍密码,这么做主要为了两点:

  1. 保证操作者是当前账号本人
  2. 增加操作步骤,防止误删除重要数据

这就是我们本篇要讲的 -------- 二级认证,即:在已登录会话的基础上,进行再次验证,提高会话的安全性。

17.1 具体API

在Sa-Token中进行二级认证非常简单,只需要使用以下API:

// 在当前会话 开启二级认证,时间为120秒
StpUtil.openSafe(120); 

// 获取:当前会话是否处于二级认证时间内
StpUtil.isSafe(); 

// 检查当前会话是否已通过二级认证,如未通过则抛出异常
StpUtil.checkSafe(); 

// 获取当前会话的二级认证剩余有效时间 (单位: 秒, 返回-2代表尚未通过二级认证)
StpUtil.getSafeTime(); 

// 在当前会话 结束二级认证
StpUtil.closeSafe(); 
17.2 使用注解进行二级认证

在一个方法上使用 @SaCheckSafe 注解,可以在代码进入之前此方法之前进行一次二级认证

// 二级认证:必须二级认证之后才能进入该方法 
@SaCheckSafe      
@RequestMapping("add")
public String add() {
    return "用户增加";
}
18 Http Basic 认证

Http Basic 是 http 协议中最基础的认证方式,其有两个特点:

  • 简单、易集成。
  • 功能支持度低。

在 Sa-Token 中使用 Http Basic 认证非常简单,只需调用几个简单的方法。

18.1 启用Http Basic 认证

首先在一个接口中,调用 Http Basic 校验:

@RequestMapping("test3")
public SaResult test3() {
    SaBasicUtil.check("sa:123456");
    return SaResult.ok();
}

然后我们访问这个接口时,浏览器会强制弹出一个表单: 当我们输入账号密码后 (sa / 123456),才可以继续访问数据。

18.2 其他启用方式
// 对当前会话进行 Basic 校验,账号密码为 yml 配置的值(例如:sa-token.basic=sa:123456)
SaBasicUtil.check();

// 对当前会话进行 Basic 校验,账号密码为:`sa / 123456`
SaBasicUtil.check("sa:123456");

// 以注解方式启用 Basic 校验
@SaCheckBasic(account = "sa:123456")
@RequestMapping("test3")
public SaResult test3() {
    return SaResult.ok();
}

// 在全局拦截器 或 过滤器中启用 Basic 认证 
@Bean
public SaServletFilter getSaServletFilter() {
    return new SaServletFilter()
            .addInclude("
@Component
public class MySaTokenListener implements SaTokenListener {

    
    @Override
    public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
        // ... 
    }

    
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        // ... 
    }

    
    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        // ... 
    }

    
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {
        // ... 
    }

    
    @Override
    public void doDisable(String loginType, Object loginId, long disableTime) {
        // ... 
    }

    
    @Override
    public void doUntieDisable(String loginType, Object loginId) {
        // ... 
    }

    
    @Override
    public void doCreateSession(String id) {
        // ... 
    }

    
    @Override
    public void doLogoutSession(String id) {
        // ... 
    }

}
22 全局过滤器

全局过滤器

23 多账号认证

多账号认证

未完待续…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667473.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号