sa-token 多端登录思路和遇到的坑
简单介绍一下sa-token
一个轻量级 Java 权限认证框架,让鉴权变得简单、优雅!
就是因为这句话,越来越多的小伙伴们开始使用sa-token,当然我也不例外,这篇文章就我在使用中遇到的问题,还有一些设计思路做一个简单的总结。也是记录一下免得以后自己忘掉了,下面进入正题。
首先简单描述一下需求,在不使用SSO以及Oauth2.0的情况下,实现IOS,安卓,WEB,PC多端登录,并且登录后有时效(有效期),在有效期内如果有一小时(或者任意时间段) 内用户未进行操作,需要把当前用户登出(当前用户所在的设备端登出,其他端不登出),而且每个设备端的登出时间段不相同(栗子:ios和安卓的有效期是30天,不需要校验多久未操作登出,web有效期为一天,但是一个小时未操作就要被登出),这个就是我当时要做的需求,希望说的比较明白了。
说一下思路,首先看一下sa-token有没有我需要的api,在登录的时候,可以通过定义SaLoginModel 来配置当前登录人的设备端以及token的超时时间,但是对于临时有效期的配置,这里是没有的。
StpUserUtil.login(user.getUserId(),new SaLoginModel() .setDevice(clientType).setTimeout(timeOut));
所以我是怎么解决的呢? 当翻阅了源码过后发现sa-token的临时有效期是通过getConfig()方法每次从配置文件中获取的,这下思路就打开了。
在官方文档中提到了自定义的StpUtil也就是StpUserUtil,在文档中展示如下
public class StpUserUtil { // 使用匿名子类 重写`stpLogic对象`的一些方法 public static StpLogic stpLogic = new StpLogic("user") { // 重写 StpLogic 类下的 `splicingKeyTokenName` 函数,返回一个与 `StpUtil` 不同的token名称, 防止冲突 @Override public String splicingKeyTokenName() { return super.splicingKeyTokenName() + "-user"; } // 同理你可以按需重写一些其它方法 ... }; }
既然可以重写StpLogic类 ,前面提到的getConfig方法就在StpLogic类中,那么我们就可以重写getConfig方法如下
// APP 端 Config static SaTokenConfig configAPP = new SaTokenConfig() { { setActivityTimeout(-1); //.. }}; // PC 端Config static SaTokenConfig configPC = new SaTokenConfig() { { setActivityTimeout(60 * 60); //.. }}; // 使用匿名子类 重写`stpLogic对象`的一些方法 public static StpLogic stpLogic = new StpLogic(TYPE) { @Override public SaTokenConfig getConfig() { try { String device = SaManager.getSaTokenDao().get("****"); if(SaTokenConf.WEB.equals(device)) { return configPC; }else if(token != null && !token.equals("null") && device != null){ return configAPP; } }catch (Exception e){ } return SaManager.getConfig(); } @Override public boolean hasPermission(String permission) { return super.hasPermission(permission); } };
在登陆时将登入人的设备类型存入到你想存的地方,我这里是存入的redis中,通过SaManager.getSaTokenDao()获取到sa-token的redis实现从而实现存储,在获取到device后,进行判断,最终拿到对应的Config,这样就可以实现在不同的设备端,拥有不同的token临时有效期。
这个方法也只是为了实现功能而写,并没有那么优雅的解决这个问题,希望看到此文章的各位同僚们,能提出你们的建议和意见。