Java实现用户异地登陆踢人操作

JavaWeb-实现多ip、异地 同时登录踢人下线 一次偶然,从朋友那里得到一份“java高分面试指南”,里面涵盖了25个分类的面试题以及详细的解析:JavaOOP、Java集合/泛型、Java中的IO与NIO、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。 阅读详情

使用框架: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,因为是自己的想法,所以,我认为自己是原创了,毕竟我也没找到其他人这么做的。


ubuntu系统禁止/开启内核自动更新 内核自动更新会导致驱动和内核版本不对应,导致驱动无法使用,所以需要禁止自动更新内核。本文介绍ubuntu系统禁止/开启内核更新的方法。 阅读详情

相关推荐

Claude Code vs Codex实战对比:哪个更适合你的Next.js项目?(含真实案例)

本文通过两个真实的Next.js项目案例,深度对比了Claude Code与Codex在UI实现和业务逻辑构建中的表现。Claude Code在代码质量、设计还原度和架构完整性方面优势明显,适合对可维护性要求高的生产级项目;而Codex则以快速响应和低成本见长,更适合原型开发或内部工具。文章提供了基于项目类型、团队能力和成本效益的详细选择策略。

weixin_29201859的博客 811

java实现踢下线用户_浅谈踢人下线的设计思路!(附代码实现方案)

前言前两天写了一篇文章,主要讲了下java中如何实现踢人下线,原文连接:java中如何踢人下线?封禁某个帐号后使其会话当即掉线!前端原本只是简单阐述一下踢人下线的业务场景和实现方案,没想到引出那么多大佬把小弟喷的睁不开眼睛,为了不你们继续喷我,特再写下此篇文章,完全讲清楚各类场景下踢人下线的设计思路,若有不足之处还请各位大佬轻喷!java好了废话很少说,正文开始算法正文若是把踢人下线比喻成拆房子,...

weixin_33821493的博客 2378

别再手动更新Excel了!用Jira看板管理你的个人项目(附保姆级配置流程)

本文详细介绍了如何利用Jira看板替代Excel进行个人项目管理,提供从注册到配置的保姆级教程。通过极简看板模式、自动化规则和数据分析功能,帮助用户实现任务可视化、协作高效化和提醒自动化,大幅提升个人工作效率。特别适合需要管理复杂个人项目的用户。

weixin_42699679的博客 229

轻量级权限框架之-Sa-ToKen

关于我重生为一名程序猿后-学习的超好用的权限认证框架之 Sa-Token

wgy_BUG的博客 998

Python3实现基于ARIMA模型来预测茅台股票价格趋势

ARIMA(Autoregressive Integrated Moving Average)模型是一种广泛使用的时间序列分析方法,它可以用于对未来的数据进行预测。ARIMA模型由自回归模型(AR模型)、差分整合模型(I模型)和移动平均模型(MA模型)组成,因此也被称为ARIMA(p,d,q)模型。其中,p表示自回归阶数,d表示差分阶数,q表示移动平均阶数。具体来说,ARIMA模型可以通过以下步骤进行建模:数据预处理:对时间序列进行平稳性检验,如果不满足平稳性,则进行差分操作。

m0_64336780的博客 2万+

【全局路径规划模块运动学算法】无人机Kinodynamic A*算法、Kinodynamic RRT*算法(附C++代码)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对Kinodynamic A*算法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容啃这个Kinodynamic A_star算法,建议先啃一啃高飞fast_planner那篇论文,把理论打好,如果还是比较迷,就先看Dijksta、再看A_star、再看hybrid A_star 三个的流程,因为往上资料比较多,再看这个Kinodynamic A_star算法,流程已经很相像了。如果。

qq_35635374的博客 2604

Java防止用户同一时间重复登录(包括异地登录)

有时候我们在做登录模块过程中难免会遇到这种问题,即使我们给用户进行了多重判断,比如:用户名,管理员,验证码,一系列的判断… 你是否真正考虑到用户的体验,比如不能让用户在同一时间,同一个浏览器重复登录问题,同时也包括不同浏览器登录(异地登录)问题。 这些都是我们应该去考虑的。如果是用Spring 框架的话,Spring security 是可以实现防止用户重复登录的问题的,但我这里并没有用到框架,因...

Brave的博客 4189

SAP录入总账凭证报错 公司代码未被分配给国家或用于计算程序的国家消息号 FF703

SAP系统报错FF703的解决方案:当公司代码未分配国家或未配置计税程序时,会导致增值税计算失败。处理方法:1)通过OX02检查公司代码国家字段;2)使用OBBG为国家分配计税程序(如TAXCN)。配置步骤:1)SPRO分配公司代码到国家;2)OBBG设置国家对应的计税程序。注意事项:历史数据需清理才能修改国家字段,不同账簿可配置不同计税程序。完成配置后即可正常处理含税凭证。

金牌架构师 560

java怎么实现踢掉在线用户_Java多人在线聊天室(3)— 踢人下线功能

作为一个聊天室,肯定会有很多人在里面聊天,那么要是有人里面捣乱怎么办?直接踢人不解释。我们在创建数据库的时候就有这样的考虑,所以我们的账户有两种,一种是管理员,一种是普通用户。打开的数据库!我们可以看见存在两种角色。那么管理员就可以把普通用户踢下线。首先就是在前端页面添加一个踢人下线的按键效果:重写一下 userbean 的 equals() 和 hashCode() 方法,这两个方法可以帮助我们...

weixin_31362539的博客 1014

【开发必备插件】iframe嵌套报“拒绝连接请求”的本地解决方法

关键词:iframe 拒绝连接、X-Frame-Options、Chrome 插件、前端调试、Allow X-Frame-Options前几天我在本地项目里调试一个第三方网站的嵌入页面时,遇到了一个非常经典的报错:xxx.com 拒绝了我们的连接请求。熟悉的老前端们一眼就知道——这是。但对于日常开发来说,我们经常需要在本地测试 iframe 嵌套外部页面(比如嵌第三方登录页、支付页、可视化报表系统等)。而线上站点配置了或DENY时,就会直接导致 iframe 加载失败。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1545

保研考研机试攻略:第一章——从零开始

🧊保研考研机试攻略:第一章——从零开始

qq_63349644的博客 1321

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

使用框架:Shiro+SpringBoot首先,我先说步骤:1.登陆2.查看该用户是否已经登陆 是:3 否:正常登陆3.将已登陆用户踢出,自己登陆。这只是说原理,具体实现现在说。踢出已登陆用户,主要体现在对已登陆用户session的处理上,原理简单,就是将已登陆用户的session删除就好。难点在于如何找到该用户的session。这里,我使用了redis首先,在登陆的时候获取用户的sessio...

weixin_36486395的博客 2027

Megatron-LM中的TP、PP、DP、SP、CP并行

SP主要优化的是激活内存,它沿序列维度切分部分激活,适用于较短序列并行。CP主要解决的是长序列的显存问题,它沿序列维度切分所有激活和输入,并且对注意力机制也进行并行处理。二者可以组合使用,特别是当 TP > 1 并且需要处理长序列时,通过启用 SP 和 CP 可以最大化地优化内存使用和加速计算。

u013250861的博客 861

java怎么实现踢掉在线用户_Java实现用户异地登陆踢人操作

使用框架:Shiro+SpringBoot首先,我先说步骤:1.登陆3.将已登陆用户踢出,自己登陆。这只是说原理,具体实现现在说。踢出已登陆用户,主要体现在对已登陆用户session的处理上,原理简单,就是将已登陆用户的session删除就好。难点在于如何找到该用户的session。这里,我使用了redis首先,在登陆的时候获取用户的sessionId,也就是浏览器中的jessionId,因为我使...

weixin_29129919的博客 1300

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Java-实现异地登陆和超时登陆

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34246551的博客 2707

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

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

一、原理1. 异地登陆同一个账号,在不同的电脑(也可以不同的浏览器)登陆系统,前一个已经登陆的账号session被销毁,用户进行下一步操作时跳转错误页面。2. 超时登陆登陆后无操作*分钟后自动销毁session,用户进行下一步操作时跳转错误页面。3. 区分异地登陆和超时登陆起效时跳转的错误页面不相同。二、实现1.超时登陆由系统控制,在web.xml中配置,或者由监听器控制,利用session.s...

weixin_42500156的博客 2572

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

用户登录风险之判断异地登陆(登陆位移速度计算)

概述 登陆位移计算也就是计算当前登陆的位置与上次登陆的位置的距离与速度,根据当前速度与一个当今社会的正常交通速度相比较,如果速度过大就可以视为有盗号风险。 球面距离计算公式 A地:(经度:Aj,纬度:Aw) B地:(经度:Bj,纬度:Bw) 两地距离: 数据支持 评估数据 登陆时间,登陆地区经纬度 历史数据 上一次登陆时间,上一次登陆经纬度 java代码示例 @Data @AllArgsC...

qq_38040765的博客 2600

Java 异地登陆账号怎么提示

异地登陆账号提示方案 1. 问题背景 在开发Web应用程序时,用户账号安全是一个重要的问题。如果用户在异地登陆账号,可能会涉及到账号被盗用的风险。因此,我们需要一个方案来实现Java异地登陆账号的提示功能。 2. 方案描述 我们可以通过记录用户的登录地点信息,当用户在新的地点登录时,系统会提示用户账号可能存在异常的情况。具...

weixin_40252124的博客 426

java web怎么实现踢人_JavaWeb-实现多ip、异地 同时登录踢人下线

JavaWeb-实现多ip、异地 同时登录踢人下线2017年06月23日 18:46:48阅读数:2666所用知识点罗列:cookie 、session、serverlet过滤器、serverlet监听器,前提环境是基于Session实现的登录功能(Session中存放了登录者的ip,userName等信息作已登录标记)12需要理解的基本概念Session是基于cookie的,请求回话中,通过浏览...

weixin_42499067的博客 775

Servlet判断用户是否登陆过、异地登录和登出功能

Servlet判断用户是否登陆过和异地登录功能 利用ServletContext+session+监听器(Listener)实现 做login界面时当用户进行登录会有用户再次登录的情况,如果一个账户两个人同时登录会有许多不必要的麻烦,针对以上情况做出了一下代码的修改 首先是两个简单的界面 login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <t

简单的男孩 1399

java实现单一登录,重复登录,用户登录后再次登录相同用户,会踢掉第一次登录用户(类似QQ登录)

java实现单一登录(类似QQ登录)一、业务需求二、具体实现实现思路具体代码 一、业务需求 账号已在web端登录后,再次登录相同账号将踢掉前一次的登录信息。 二、具体实现 实现思路 1.通过定义一个全局map变量sessionMap来保存用户登录成功时session对象,key为userId,value为HttpSession对象。 2.用户登录成功时将用户信息及session存入sessionMap(同一浏览器session相同)。 3.定义一个全局拦截器Interceptor,拿当前session对象与

清风的博客 3331
上一篇: pycharm更新pip失败解决方法
下一篇: 关于interceptor拦截器跨域response.addHeader("Access-Control-Allow-Origin", "*");不生效的情况
shadowTime
博客等级 码龄9年 1粉丝 6原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值