JavaWeb如何实现限制单个账号多处登录
在网上有很多解决限制登录的方法,包括SpringSecurity也有解决的方案,今天记录一下使用JavaWeb的实现
知识点
思路如下:
演示
具体实现:
1.维护一个map集合
public class LoginUserMap { private static Map<String, String> loginUserMap = new ConcurrentHashMap<String, String>(); /** * set方法 * * @param loginId 用户唯一标识,用户名或者用户Id * @param sessionId sessionId */ public static void setLoginUserMap(String loginId, String sessionId) { loginUserMap.put(loginId, sessionId); } /** * get方法 * * @return */ public static Map<String, String> getLoginUserMap() { return loginUserMap; } /** * 根据sessionId移除map中的值 * * @param sessionId */ public static void removeUser(String sessionId) { for (Map.Entry<String, String> entry : loginUserMap.entrySet()) { if (sessionId.equals(entry.getValue())) { loginUserMap.remove(entry.getKey()); break; } } } /** * 判断用户是否在map中 * * @param loginId * @param sessionId * @return */ public static boolean isInLoginUsers(String loginId, String sessionId) { return (loginUserMap.containsKey(loginId) && sessionId.equals(loginUserMap.get(loginId))); }
2.实现一个session监听
session销毁能及时更新map
@WebListener public class SessionListener implements HttpSessionListener { private Logger logger=LoggerFactory.getLogger(SessionListener.class); @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { HttpSession session = httpSessionEvent.getSession(); String sessionId = session.getId(); //session销毁时消除loginUserMap中的sessionId LoginUserMap.removeUser(sessionId); logger.info("session销毁,sessionId:"+sessionId); } }
3.定义过滤器
可自定义一个过滤器,但要排除登录请求(略),核心代码如下
//判断是否重复登录 String loginName = username.getLoginName();//获取用户唯一标识 //判断当前用户session是否改变 if (!LoginUserMap.isInLoginUsers(loginName,session.getId())) { //定义自己的实现方式,被挤下线,我的是: //session发送改变,表示别处登录 //被挤下线,清除session,提示信息,实现跳转 request.setAttribute("online",false); request.getRequestDispatcher("/logout.do").forward(request,response); return; } chain.doFilter(new XssHttpSerlet((HttpServletRequest) request), response);
4.注册监听和过滤器
<filter> <filter-name>LoginLimitFilter</filter-name> <filter-class>io.github.brightloong.loginlimite.LoginLimitFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginLimitFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
另外,可以设置轮询的方式判断,让用户及时下线,但消耗资源,我采取的是请求失败跳转的方式,直接调用退出登录的接口
总结
实现无法解决同一浏览器多次登录的问题,及sessionId相同,但能实现基本的限制登录的操作,因为做的是踢线下,所以相比账号在线,无法登录来说,稍微简单,若做第二种形式,则需要考虑session是否消除的问题。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Spring Cloud Gateway远程命令执行漏洞分析(CVE-2022-22947)
使用Spring Cloud Gateway的应用程序在Actuator端点启用、公开和不安全的情况下容易受到代码注入的攻击,攻击者可以恶意创建允许在远程主机上执行任意远程执行的请求,这篇文章主要介绍了Spring Cloud Gateway远程命令执行漏洞(CVE-2022-22947),需要的朋友可以参考下2023-03-03springboot+thymeleaf+layui的实现示例
本文主要介绍了springboot+thymeleaf+layui的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-12-12Spring Security 自动踢掉前一个登录用户的实现代码
这篇文章主要介绍了Spring Security 自动踢掉前一个登录用户的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-05-05idea快捷键生成getter和setter,有构造参数,无构造参数,重写toString方式
这篇文章主要介绍了java之idea快捷键生成getter和setter,有构造参数,无构造参数,重写toString方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-11-11
最新评论