java 实现异地登陆_Java实现用户异地登陆踢人操作
使用框架: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 ChariotResponseEntitylogin(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 实现异地登陆_Java实现用户异地登陆踢人操作相关推荐
- java在线客服_java 网站用户在线和客服聊天
这是应用到项目中的一个例子. 实现原理是将信息存储到Application域里面.然后使用Struts2 Action 用json格式的数据进行前后台交互. 截图: 前台用户界面: 后台客服界面: 编 ...
- java实现自动登录_java实现用户自动登录
自动登录,是为了帮助用户多次使用这个网页时,不用再次输入用户名和密码就可以登录. 自动登录是指用户将用户的登录信息,人,保存到本地的文件中Cookie中. Name,value -声明时 new Co ...
- java中修改密码_java中用户密码加密时增加和修改的代码
建一个MD5.java类 package util; /************************************************ MD5 算法的Java Bean Last M ...
- java swing 等待框_java – 让用户使用Swing等待
我想让用户等待一段时间(10秒).我知道在JSP或servlet中我们使用META标记< META HTTP-EQUIV ="Refresh"CONTENT ="3 ...
- java模拟点击_java 模拟用户点击事件
展开全部 调用按62616964757a686964616fe59b9ee7ad9431333365656630钮的 doClick() 方法,下例演示了 button2 模拟点击 button1 按 ...
- java stream 分组求和_Java stream List 求和、分组操作
Java stream List 求和.分组操作 前言 项目中经常会使用Stream操作一些集合数据,今天记录一下我经常使用的Stream操作 求和操作public static void main( ...
- JAVA编程TXT文件_java开发之读写txt文件操作的实现
项目结构: 运行效果: ======================================================== 下面是代码部分: ====================== ...
- java list 删除 遍历_Java list利用遍历进行删除操作3种方法解析
Java list利用遍历进行删除操作3种方法解析 这篇文章主要介绍了Java list利用遍历进行删除操作3种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需 ...
- java web定义数组_Java基础之数组--数组常用操作
3.2一维数组 3.2.1声明数组 数组类型[] 数组名称:int[] username; 或者 数组类型 数组名称[];int username[]; 3.2.2初始化一维数组 一维数组初始化有两种 ...
最新文章
- MATLAB实时标定
- Matlab R2010在centost下的安装
- 组态王与c语言混合编程6,亚控 组态王嵌入版6.1
- 蓝桥杯-矩阵相乘(java)
- springboot的yml配置文件绑定时必须和相应的类中的属性类型对应,不然启动报错
- 300小时成为java程序员_直击面试现场: Java程序员3轮6小时面试, 成功拿到阿里offer!...
- python去重计数_用Python实现透视表的value_sum和countdistinct功能
- Auto CAD 2020 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 全版本 附带安装教程+入门到精通视频教程
- 深度解析脑机接口技术的现状与未来!
- 【Qt】绘制CIE色度图
- Java将数字金额转换为中文大写
- cad直线和圆弧倒角不相切_数控加工中心如何使用任意角度倒角C和倒圆角R功能的编程...
- git如何查看缓存区文件内容_[暂存盘已满怎么解决]git暂存区的理解
- RuntimeError: DataLoader worker (pid 4499) is killed by signal: Segmentation fault.检查内存条!
- OpenCv阈值化处理cv2.threshold()函数
- USYD悉尼大学DATA 2002 【R语言学习1】【介绍R】Introduction to R「虽迟但到」
- Excel按相同列内容合并表
- 机器学习之提升方法Adaboost算法
- redis incr命令最大值问题
- java 集合封装树形结构