JavaWeb如何实现限制单个账号多处登录

 更新时间:2024年08月13日 14:33:09   作者:咕噜咕噜da  
这篇文章主要介绍了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远程命令执行漏洞分析(CVE-2022-22947)

    使用Spring Cloud Gateway的应用程序在Actuator端点启用、公开和不安全的情况下容易受到代码注入的攻击,攻击者可以恶意创建允许在远程主机上执行任意远程执行的请求,这篇文章主要介绍了Spring Cloud Gateway远程命令执行漏洞(CVE-2022-22947),需要的朋友可以参考下
    2023-03-03
  • springboot+thymeleaf+layui的实现示例

    springboot+thymeleaf+layui的实现示例

    本文主要介绍了springboot+thymeleaf+layui的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-12-12
  • SpringMVC实现用户登录全过程

    SpringMVC实现用户登录全过程

    这篇文章主要介绍了SpringMVC实现用户登录全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • Spring Security 自动踢掉前一个登录用户的实现代码

    Spring Security 自动踢掉前一个登录用户的实现代码

    这篇文章主要介绍了Spring Security 自动踢掉前一个登录用户的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • 深入理解什么是Mybatis懒加载(延迟加载)

    深入理解什么是Mybatis懒加载(延迟加载)

    这篇文章主要介绍了深入理解什么是Mybatis懒加载(延迟加载),mybatis的懒加载,也称为延迟加载,是指在进行关联查询的时候,按照设置延迟规则推迟对关联对象的select查询,延迟加载可以有效的减少数据库压力,需要的朋友可以参考下
    2023-10-10
  • 如何有效管理JVM中的垃圾?

    如何有效管理JVM中的垃圾?

    今天给大家带来的是关于Java虚拟机的相关知识,文章围绕着如何有效管理JVM中的垃圾展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 基于Jenkins自动打包并部署docker环境的操作过程

    基于Jenkins自动打包并部署docker环境的操作过程

    这篇文章主要介绍了基于Jenkins自动打包并部署docker环境,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • java多线程之线程同步七种方式代码示例

    java多线程之线程同步七种方式代码示例

    这篇文章主要介绍了java多线程之线程同步七种方式代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • idea快捷键生成getter和setter,有构造参数,无构造参数,重写toString方式

    idea快捷键生成getter和setter,有构造参数,无构造参数,重写toString方式

    这篇文章主要介绍了java之idea快捷键生成getter和setter,有构造参数,无构造参数,重写toString方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • springboot 重定向方式(redirect前缀)

    springboot 重定向方式(redirect前缀)

    这篇文章主要介绍了springboot 重定向方式(redirect前缀),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论