用户登录相关问题

问题描述

目前系统包括一个Web网站系统和一个微信公众号,Web网站系统和微信公众号共用相同的用户信息。需要实现的功能是Web网站系统用户登录系统后,当在其他地方同时登录该用户信息,能够将前面那个用户挤下来并让后面那个用户信息登录(和微信多个地方登录类似);而微信公众号则若用户登录微信公众号,需要先绑定用户信息,绑定成功后,微信公众号用户将不需要再次登录,除非退出或者openID失效,而其他用户再次用这个账号绑定微信公众号时将不再绑定成功。同时微信公众号和Web网站系统能够同时同一个用户在线,当管理员将用户删除后,Web用户能够及时下线及微信公众号退出。

问题处理

  • Web网站系统:用户一开始登录,将用户ID和sessionID写入到Redis数据库中(键值对保存)及将用户信息、登录类型写入session
  • 微信公众号:微信公众号绑定及登录,将公众号的OpenID和sessionID写入到Redis数据库(键值对保存)及将用户信息、登录类型写入session
  • 编写一个过滤器,对所有需要登录权限的请求拦截,获取用户的登录类型及用户信息

    • 用户未登录,则直接提示用户未登录,返回到登录界面
    • 用户已登录且为微信登录,则根据用户的openID获取保存在Redis中的sessionID
    • 用户已登录且为Web网站系统用户,则根据用户的ID获取保存在Redis中sessionID
    • 若redis中保存的sessionID为空,则提示用户未登录系统
    • 若Redis中保存的sessionID不为空且和当前用户的sessionID不一样,则当前用户被挤下来了,需要清除session并返回到登录界面
    • 若Redis中保存的sessionID不为空且和当前用户的sessionID一样,则继续
    • 当删除用户后,需要将Redis清空
  • 系统需要监听sesison创建和销毁,当session销毁时,需要清理session中redis中缓存的数据

  • 系统设置为30分钟session过期,微信公众号需要自己根据OpenID自动登录微信公众号

问题解决

  • 用户登录:
        if(user==null){
            throw new PhyException(PhyException.NoEntity,"请填写用户信息");
        }
        User user2 =userService.loading(user.getLoginName(), user.getTextPwd());
        if (user2 != null) {
            session.setAttribute("user", user2);
            session.setAttribute("loginType", "web");
            userSessionRedisService.add(user2.getId(), session.getId());
            return true;
        } else{
            throw new PhyException(PhyException.Error,"账户信息或者密码不正确!!");
        }
  • 用户退出:
User user=(User)session.getAttribute("user");
        if(user==null){
            return false;
        }
        session.invalidate();
        return false;
  • 微信绑定、微信登录和解绑类似。
  • 用户删除:
User user=(User)session.getAttribute("user");
        if(user!=null){
            if(ids.contains(user.getId())){
                throw new PhyException(PhyException.HasEntity,"无法删除当前用户信息!!");
            }
        }
        List<String> openIds=userService.findOpenIds(ids);
        if(userService.delete(ids)){
            if(openIds!=null&&openIds.size()>0){
                ids.addAll(openIds);
            }
            userSessionRedisService.delBatch(ids);
            return true;
        }
        return false;
  • 权限过滤器:
HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session=request.getSession();
        String uriString = request.getRequestURI();
        String uriMethod = request.getMethod();
        String currSession=session.getId();
        /*
         * Http中允许接入的方法
         */
        if(uriMethod.equals("GET") || uriMethod.equals("POST")||uriMethod.equals("DELETE")||uriMethod.equals("PUT")){
            //游客
            if(!(uriString.contains("/admin/")||uriString.contains("/common/"))){
                logger.debug("游客用户登录!!");
                chain.doFilter(request, response);
                return;
            }
            User user=(User)session.getAttribute("user");
            //用户未登录
            if(user==null){
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                return ;
            }
             String type=(String)session.getAttribute("loginType");
             String sessionId=null;
             if(type!=null&&type.equals("wechat")){
                 sessionId=userSessionRedisService.get(user.getOpenId());
             }else{
                 sessionId=userSessionRedisService.get(user.getId());
             }
            //未登录系统
            if(StrUtil.isBlank(sessionId)){
                response.setStatus(510);
                Map<String, Object> maps=new HashMap<String, Object>();
                maps.put("code", PhyException.NoLogin);
                maps.put("msg", "用户未登录系统!!");
                session.invalidate();
                response.getOutputStream().write(ReturnFormat.retParam(maps).getBytes());
                return ;
            }else if(!sessionId.equals(currSession)){//判断用户是否是同一个用户
                    response.setStatus(510);
                    session.invalidate();
                    Map<String, Object> maps=new HashMap<String, Object>();
                    maps.put("code", PhyException.HasMore);
                    maps.put("msg", "用户已经其他地方登录了!!");
                    response.getOutputStream().write(ReturnFormat.retParam(maps).getBytes());
                    return ;
            }
            switch(user.getRole()){
                case Admin:
                    if(uriString.contains("/admin/")||uriString.contains("/common/")){
                        logger.debug("超级管理员登录!!");
                        chain.doFilter(req, res);
                        return;
                    }
                case Common:
                    if(uriString.contains("/common/")){
                        logger.debug("普通管理员登录!!");
                        chain.doFilter(req, res);
                        return ;
                    }
            }
            //认证失败
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return ;
        }
        //禁止使用
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        return;
  • session监听器:
public void sessionCreated(HttpSessionEvent arg0) {
        logger.info("User Session Create");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
    //获取spring bean,session redis操作 bean
        ApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(sessionEvent.getSession().getServletContext());
        UserSessionRedisService userSessionRedisService = (UserSessionRedisService)wac.getBean("userSessionRedisServiceImpl"); 
        //根据不同登录类型,删除redis中保存的session信息
        HttpSession session=sessionEvent.getSession();
        User user=(User)session.getAttribute("user");
        String type=(String)session.getAttribute("loginType");
        if(user!=null){
            if(type!=null&&type.equals("wechat")){
                userSessionRedisService.del(user.getOpenId(),session.getId());
            }else{
                userSessionRedisService.del(user.getId(),session.getId());
            }
            logger.info("User Session Destroy,userId:"+user.getId());
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值