zoukankan      html  css  js  c++  java
  • 实现同用户登录互挤,将前一个用户挤下线(思路+实现)

     由于对用户数据的安全性考虑,在同一时刻不允许两个相同的用户存在(SSM架构下)。

    场景,假设 Tom使用了用户1,Joker也是使用了用户1,两人同时对用户1 的相关数据进行了修改,就会造成数据的安全隐患。

    思路:

      1.定义一个key-value结构的用户栈,将用户名与sessionId绑定,存入用户栈中

      2.设置拦截器,拦截请求,判断该用户的sessionId是否与系统中的sessionId一致

        这里的用户栈可以使用ServletContext,其作用域为application,在用户登录成功的时候,将sessionId存入ServletContext,并在拦截过程中,以用户名为Key值判断sessionId的一致性。

    实现:

    在controller的登录方法dologin中:

        @RequestMapping(value="/dologin",method = RequestMethod.POST)
        public String dologin(@RequestParam User user,
                    HttpSession session, Model model){
         //获取ServletContext对象 ServletContext application = session.getServletContext();
         //查找数据库中的用户信息 User loginUser=userService.login(user);if(loginUser!=null){ //账号密码正确 String sessionId = session.getId();
    if(application.getAttribute(userName) == null){ application.setAttribute(userName,sessionId); }else if (application.getAttribute(userName)!= null && !StringUtils.equals(sessionId,application.getAttribute(userName).toString())){ application.removeAttribute(userName); application.setAttribute(userName,sessionId); }
            //将用户信息存入session中 session.setAttribute("user", user); // 页面跳转main.jsp return "main"; }else{ //账号密码错误 model.addAttribute("error", "账号密码不正确");return "login"; }
      }

    拦截器userInterceptor

    public class userInterceptor implements HandlerInterceptor {
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    
        }
    
        @Override
        public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
           
            User user=(User)httpServletRequest.getSession().getAttribute("user");
            String indexurl=httpServletRequest.getRequestURL().toString().replace(httpServletRequest.getRequestURI(),"");
            ServletContext application = httpServletRequest.getSession().getServletContext();
    
            if(user!=null){   //session中存在用户信息
                String sessionId=application.getAttribute(operator.getUserName()).toString();
    
                if(sessionId.equals(httpServletRequest.getSession().getId())){
                    //请求的sessionId和此账号的sessionId一致,允许请求return true;
                }else{
                    //如果请求的sessionId和此账号的sessionId不一致,跳转至异地登录提示页面
                    httpServletResponse.sendRedirect(indexurl+"/relogin");
                   return false;
                }
            }
            //第一次登陆系统,session中没有记录,转发通过
            httpServletRequest.getRequestDispatcher(indexurl).forward(httpServletRequest, httpServletResponse);
            return true;
        }
    
    }

    配置文件中设置拦截路径

    <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/**"/>
           <mvc:exclude-mapping path="/statis/**"/> //exclude-mapping 不拦截的路径
           <mvc:exclude-mapping path="/dologin"/> <bean class="yi.survey.interceptor.UserInterceptor"/> </mvc:interceptor> </mvc:interceptors>

    说明:

      后一个用户登录系统时,会替换用户栈对应的sessionId,需要前一个用户发起任意请求时,才会被强制跳转到异地登录提示页面

  • 相关阅读:
    Java中将Map转换为JSON
    使用net.sf.json.JSONObject 解析Json数据
    JavaScript 资源大全中文版
    leetcode练习:693. Binary Number with Alternating Bits
    leetcode练习:455. Assign Cookies
    自写~模拟操作系统进程调度C语言(按优先级)
    leetcode练习:441. Arranging Coins
    leetcode练习:258. Add Digits & 415. Add Strings
    leetcode练习:504. Base 7
    leetcode练习:561. Array Partition I
  • 原文地址:https://www.cnblogs.com/yhood/p/11593375.html
Copyright © 2011-2022 走看看