| | |
| | | |
| | | private final static String ACCESS_TOKEN_STUDY = CacheConstants.LOGIN_TOKEN_KEY_STUDY; |
| | | |
| | | private final static String ACCESS_TOKEN_PARENT = CacheConstants.LOGIN_TOKEN_KEY_PARENT; |
| | | |
| | | private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; |
| | | |
| | | /** |
| | |
| | | */ |
| | | public LoginUserParent getLoginUser1(String token) { |
| | | LoginUserParent user = null; |
| | | try { |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | try { |
| | | String userkey = JwtUtils.getUserKey1(token); |
| | | user = redisService.getCacheObject(getTokenKey(userkey)); |
| | | return user; |
| | | } |
| | | user = redisService.getCacheObject(getTokenKeyParent(userkey)); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | // 单设备登录校验:账号已在其他设备登录时,将先登录的设备强制下线 |
| | | // 注意:此处不能放在 try 中,否则会被 catch(Exception) 吞掉异常 |
| | | if (user != null && !Boolean.TRUE.equals(user.getIsCanLogin())) { |
| | | throw new StudyLoginException("当前登录账号在其他设备登录!", 505); |
| | | } |
| | | } |
| | | return user; |
| | | } |
| | |
| | | public void delLoginUser1(String token) { |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | String userkey = JwtUtils.getUserKey1(token); |
| | | redisService.deleteObject(getTokenKey(userkey)); |
| | | redisService.deleteObject(getTokenKeyParent(userkey)); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 家长端用户登录 |
| | | * 家长端用户登录(单设备登录:新设备登录后,将先登录的设备挤下线) |
| | | */ |
| | | public void refreshToken1(LoginUserParent dto) { |
| | | // 获取所有 login_tokens_parent: 前缀的登录缓存 |
| | | Set redisCache = redisService.getKeysPrefix(ACCESS_TOKEN_PARENT); |
| | | for (Object key : redisCache) { |
| | | String strKey = String.valueOf(key); |
| | | Object redisCacheUserInfo = redisService.getCacheObject(strKey); |
| | | LoginUserParent redisUserInfo = JSONObject.parseObject(JSONObject.toJSONString(redisCacheUserInfo), LoginUserParent.class); |
| | | // 单点逻辑:同一账号已在其他设备登录,则把先登录的 token 置为不可登录 |
| | | if (dto.getUserid().equals(redisUserInfo.getUserid())) { |
| | | // 已被挤下线的 token 直接跳过,避免重复写缓存 |
| | | if (!Boolean.TRUE.equals(redisUserInfo.getIsCanLogin())) { |
| | | continue; |
| | | } |
| | | // isCanLogin 为 false 表示该 token 已被其他设备挤下线 |
| | | redisUserInfo.setIsCanLogin(Boolean.FALSE); |
| | | // 使用原有过期时间续写,避免踢下线反而延长了旧 token 的生命周期 |
| | | redisService.setCacheObject(strKey, redisUserInfo, redisService.getExpire(strKey), TimeUnit.SECONDS); |
| | | } |
| | | } |
| | | dto.setLoginTime(System.currentTimeMillis()); |
| | | dto.setExpireTime(dto.getLoginTime() + expireTime * MILLIS_MINUTE); |
| | | // 根据uuid将loginUser缓存 |
| | | String userKey = getTokenKey(dto.getToken()); |
| | | String userKey = getTokenKeyParent(dto.getToken()); |
| | | redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES); |
| | | } |
| | | |
| | |
| | | return ACCESS_TOKEN_STUDY + token; |
| | | } |
| | | |
| | | private String getTokenKeyParent(String token) { |
| | | return ACCESS_TOKEN_PARENT + token; |
| | | } |
| | | |
| | | } |