开发者

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

开发者 https://www.devze.com 2024-08-14 10:27 出处:网络 作者: 咕噜咕噜da
目录知识点演示1.维护一个map集合2.实现一个session监听3.定义过滤器4.注册监听和过滤器总结在网上有很多解决限制登录的方法,包括SpringSecurity也有解决的方案,今天记录一下使用JavaWeb的实现
目录
  • 知识点
  • 演示
    • 1.维护一个map集合
    • 2.实现一个session监听
    • 3.定义过滤器
    • 4.注册监听和过滤器
  • 总结

    在网上有很多解决限制登录的方法,包括SpringSecurity也有解决的方案,今天记录一下使用JavaWeb的实现

    知识点

    思路如下:

    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
         * @javascriptreturn
      python   */
        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
        pythonpublic void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            HttpSession session = httpSessionEvent.getSession();
            String sessionId = session.getId();
            //session销毁时消除loginUserMap中的sessionId
            LoginUserMap.removeUser(sessionId);
            logger.info("session销毁,sessionId:"+sessionId);
        }
    }

    3.定义过滤器

    可自定义一个过滤器,但要排除登录请求(略),核心代码如下

     				//判断是否重javascript复登录
                    String loginName = username.getLoginName();//获取用户唯一标识
                    //判断当前用户session是否改变
                    if (!LoginUsjavascripterMap.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是否消除的问题。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号