使用框架:Shiro+SpringBoot

首先,我先说步骤:

1.登陆

2.查看该用户是否已经登陆 是:3   否:正常登陆

3.将已登陆用户踢出,自己登陆。

这只是说原理,具体实现现在说。

踢出已登陆用户,主要体现在对已登陆用户session的处理上,原理简单,就是将已登陆用户的session删除就好。

难点在于如何找到该用户的session。

这里,我使用了redis

首先,在登陆的时候获取用户的sessionId,也就是浏览器中的jessionId,因为我使用的是shiro框架,方法如下:

 Subject user = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(phone, MD5Utils.getMD5Str(password).toCharArray());  //DigestUtils.md5Hex(password).toCharArray());//token.setRememberMe(true);try {user.login(token);user.getSession().setTimeout(-1000L); // 开发时设置永不过期,上线时需要调整 todo} catch (UnknownAccountException e) {logger.error("账号不存在:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (DisabledAccountException e) {logger.error("账号未启用:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_NOT_ENABLED);} catch (IncorrectCredentialsException e) {logger.error("密码错误:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (RuntimeException e) {logger.error("未知错误,请联系管理员:{}" + e.toString(), e);System.out.println(e.toString());return new ChariotResponseEntity<>(ChariotHttpStatus.USER_OTHER_REASON);}SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();String sessionId = String.valueOf(user.getSession().getId());

主要是其中这段

        SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();String sessionId = String.valueOf(user.getSession().getId());

拿到当前登陆用户的sessionId之后,就该获取存入redis中的在这之前登陆的用户的sessionId,

这里我要解释一下sessionId的存取的现实操作步骤:

(背景:A用户没有登陆。)

1.A用户登陆,并获取A用户的sessionId

  Subject user = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(phone, MD5Utils.getMD5Str(password).toCharArray());  //DigestUtils.md5Hex(password).toCharArray());//
//        token.setRememberMe(true);try {user.login(token);user.getSession().setTimeout(7*24*3600*1000); // 开发时设置永不过期,上线时需要调整 todo} catch (UnknownAccountException e) {logger.error("账号不存在:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (DisabledAccountException e) {logger.error("账号未启用:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_NOT_ENABLED);} catch (IncorrectCredentialsException e) {logger.error("密码错误:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (RuntimeException e) {logger.error("未知错误,请联系管理员:{}" + e.toString(), e);System.out.println(e.toString());return new ChariotResponseEntity<>(ChariotHttpStatus.USER_OTHER_REASON);}SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();String sessionId = String.valueOf(user.getSession().getId());//这个就是A的sessionId

2.从redis根据条件获取sessionId,当然,因为之前并没有存入,所以获取不到,这里的条件是phone+“redist“,保证唯一

 String sessionId2 = jedisConfiguration.getJedisClient().get(phone+"redis");

3.判断sessionId2是否为空,如果为空的话,就走第4步,否则,就先根据sessionId2获取sessionKey,再根据sessionKey获取session,然后根据sessionManager删除指定session,也就是我们希望踢掉的用户的session

if(StringUtil.isNotEmpty(sessionId2)) {SessionKey sessionKey = new WebSessionKey(jedisConfiguration.getJedisClient().get(phone+"redis"),request,response);try {Session session = securityManager.getSession(sessionKey);if(!sessionId.equals(sessionId2))sessionManager.getSessionDAO().delete(session);}catch (Exception e){e.printStackTrace();}jedisConfiguration.getJedisClient().del(phone+"redis");}

4.这步也就结束了,将新用户的sessionId存入redis,方便被下一个用户踢

jedisConfiguration.getJedisClient().set(phone + "redis", sessionId);

这里是总代码,至于redis什么的,相信你们都会的。

 public ChariotResponseEntity<UserVO> login(String phone, String password,HttpServletRequest request,HttpServletResponse response) throws Exception {logger.info("POST请求登录");if (StringUtils.isBlank(phone) || StringUtils.isBlank(password)) {return new ChariotResponseEntity<>(ChariotHttpStatus.USER_PARAMETER_ERROR);}Subject user = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(phone, MD5Utils.getMD5Str(password).toCharArray());  //DigestUtils.md5Hex(password).toCharArray());//token.setRememberMe(true);try {user.login(token);user.getSession().setTimeout(-1000L); // 开发时设置永不过期,上线时需要调整 todo} catch (UnknownAccountException e) {logger.error("账号不存在:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (DisabledAccountException e) {logger.error("账号未启用:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_NOT_ENABLED);} catch (IncorrectCredentialsException e) {logger.error("密码错误:{}", e);return new ChariotResponseEntity<>(ChariotHttpStatus.USER_ACCOUNT_OR_PASSWORD_ERROR);} catch (RuntimeException e) {logger.error("未知错误,请联系管理员:{}" + e.toString(), e);System.out.println(e.toString());return new ChariotResponseEntity<>(ChariotHttpStatus.USER_OTHER_REASON);}SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();String sessionId = String.valueOf(user.getSession().getId());String sessionId2 = jedisConfiguration.getJedisClient().get(phone+"redis");if(StringUtil.isNotEmpty(sessionId2)) {SessionKey sessionKey = new WebSessionKey(jedisConfiguration.getJedisClient().get(phone+"redis"),request,response);try {Session session = securityManager.getSession(sessionKey);if(!sessionId.equals(sessionId2))sessionManager.getSessionDAO().delete(session);}catch (Exception e){e.printStackTrace();}Long result = jedisConfiguration.getJedisClient().del(phone+"redis");}String result1 = jedisConfiguration.getJedisClient().set(phone + "redis", sessionId);UserVO retUser = userService.getUserById(getCurrentUserId());return new ChariotResponseEntity<>(retUser, ChariotHttpStatus.OK);}

如果以上代码看着头痛,可以看我截取的部分

SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager();DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager();String sessionId = String.valueOf(user.getSession().getId());String sessionId2 = jedisConfiguration.getJedisClient().get(phone+"redis");if(StringUtil.isNotEmpty(sessionId2)) {SessionKey sessionKey = new WebSessionKey(jedisConfiguration.getJedisClient().get(phone+"redis"),request,response);try {Session session = securityManager.getSession(sessionKey);if(!sessionId.equals(sessionId2))sessionManager.getSessionDAO().delete(session);}catch (Exception e){e.printStackTrace();}Long result = jedisConfiguration.getJedisClient().del(phone+"redis");}String result1 = jedisConfiguration.getJedisClient().set(phone + "redis", sessionId);

个人感觉,我这样写的好处是准确的取到session,不用遍历,因为我在网上只看到过遍历出来取到的session,因为是自己的想法,所以,我认为自己是原创了,毕竟我也没找到其他人这么做的。

Java实现用户异地登陆踢人操作相关推荐

  1. java 实现异地登陆_Java实现用户异地登陆踢人操作

    使用框架:Shiro+SpringBoot 首先,我先说步骤: 1.登陆 2.查看该用户是否已经登陆 是:3   否:正常登陆 3.将已登陆用户踢出,自己登陆. 这只是说原理,具体实现现在说. 踢出已 ...

  2. 同一个用户异地登陆踢人操作

    我的实现:webSocket 其他实现: 1.http://www.caotama.com/86559.html 不要使用cookie保持登录. 1.登陆时使用帐号密码登录,后端清除该账户所有toke ...

  3. java 实现登录超时,Java-实现异地登陆和超时登陆

    一.原理 1. 异地登陆 同一个账号,在不同的电脑(也可以不同的浏览器)登陆系统,前一个已经登陆的账号session被销毁,用户进行下一步操作时跳转错误页面. 2. 超时登陆 登陆后无操作*分钟后自动 ...

  4. 微光集市-登陆后用户对购物车的操作(版本4.0)

    本文承接上文-微光集市-基于Security的用户登录功能及用户注册功能(版本3.0) 文章目录 登陆后用户对购物车的操作 1 获得登录用户购买商品数量,及将固定用户修改为当前用户 1.1 客户端 1 ...

  5. 计算机为什么会出现网络用户,电脑登陆QQ经常提示异地登陆是怎么回事?

    现在全国使用移动宽带的用户很多,相信长时间使用移动宽带的用户发现了这么一个规律,那就是你使用网络的环境没变,但是IP地址却全国跑.有时候连QQ都会被认为是异常登陆,那么这是什么原因呢?下面一起来看看关 ...

  6. 计算机为什么会出现网络用户,电脑登陆QQ经常提示异地登陆是怎么回事

    摘要 腾兴网为您分享:电脑登陆QQ经常提示异地登陆是怎么回事,指南针,信和财富,小书亭,小红书等软件知识,以及谷歌星空,小猪佩奇表情包,2018年历,全球自选,短视频工具,古墓倩影,房洽洽,中医通,c ...

  7. java 防止用户重复登录_JAVA 如何避免用户的重复登录

    展开全部 读懂下面代码,就知道如何实现 一个用户登陆 踢掉之前登陆的用户了//第一步 // 此监听62616964757a686964616fe4b893e5b19e31333337626166器用来 ...

  8. php做异地登录验证,PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】

    本文实例讲述了PHP实现用户异地登录提醒功能的方法.分享给大家供大家参考,具体如下: 对于安全性要求比较高的web网站,特别是后台管理,有时候需要甄别自己的账号是否被盗或者是否有另一个人此刻登陆了在进 ...

  9. 禁止多人使用同一账号在系统上进行操作[踢人操作]

    在开发中遇到一个问题,系统内,同一个账号可以在不同的地方多个人同时进行登陆,操作. 要求是同一账号在系统内必须保持唯一,即,若是有人用同一账号登陆了,已登录账号失效 解决方案有两种: 一种是在系统中设 ...

最新文章

  1. vue2.0 通过ip访问自己运行的项目
  2. Redis数据库(一)——Redis简介、部署及常用命令
  3. Linux中find命令详解
  4. 利用位运算解决 N 皇后问题
  5. red hat linux 远程,Red Hat Linux 远程桌面 – 如何设置
  6. thinkphp5范围查询_ThinkPHP 区间查询
  7. 【云计算的1024种玩法】10分钟轻松设置出 A+ 评分的 HTTP/2 网站
  8. python 空列表对象的布尔值_python – 从TensorFlow对象中检索数据 – 来自correct_prediction的布尔值列表...
  9. 超像素 Superpixel
  10. android禁止电话功能,#Android# 启用“阻止模式”功能,避免半夜电话骚扰!
  11. 一周学会linux实战 下载 pdf_UOS可用的pdf编辑工具
  12. 服务器装系统不识别硬盘分区,安装系统无法识别分区解决方法
  13. Java获取本机ip地址的代码
  14. ROHS认证是什么?
  15. [转载]什么是打新股? 打新股需要多少成本?打新股存在风险吗?
  16. PowerBI动态M查询参数
  17. 从Dijkstra谈帅才的洞察力(王选)
  18. 数学小课堂:库尔贝勒交叉熵(K-L divergence,也叫KL散度)【量化度量错误预测所要付出的成本,避免制订出与事实相反的计划】
  19. 树莓派计算模块CM4搭建软路由OpenWrt+OpenClash过程记录
  20. CSS+DIV设计导航条源代码

热门文章

  1. 海明校验码原理(详解)
  2. 足球战术训练的几种方法
  3. 数据结构与算法——深入理解哈希表
  4. Discord/MidJourney注册遇到电话号码无效 invalid phone number
  5. HDU 1208(Pascal's Travels)
  6. 电脑无法分屏,连接两个显示器,但只能检测到一个显示器,且只有一个显示器有画面
  7. redhat linux 7.2系统安装详细过程
  8. 如何修复Word文档XML提示
  9. android 百度 全景图,百度地图全景图
  10. 人工智能可预测阿茨海默症病情演变