美文网首页
java 单用户登录

java 单用户登录

作者: _Rondo | 来源:发表于2018-04-02 10:21 被阅读0次

    一、概述

    老项目做的app服务,提升用户体验,新加的单用户登录,注意是单用户不是单点,这里不涉及服务集群,有需求需要自己进行拓展,没用框架,是ejb3.0 servlet2.5,前后端分离;大体的逻辑为在过滤器中添加cookie登录验证,流程图如下:


    单用户登录.jpg

    二、代码示例

    1.Filter

    package com.mainsoft.online.sso;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.alibaba.fastjson.JSONObject;
    import com.mainsoft.online.station.ServiceProxy;
    import com.mainsoft.online.util.MyRequestWrapper;
    
    /**
     * 1.cookie存在, 非第一次登录,存在进行cookie登录,登录成功对比sessionid,不一致改写PWD库,一致放行
     * 2.cookie不存在, 第一次登录,转发至ajaxservlet        
     * @author sxycw 
     */
    public class LoginFilter implements Filter{
    
        @Override
        public void destroy() {
        }
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp,
                FilterChain chain) throws IOException, ServletException {
            
             //TODO 挖坑: 单系统soo,就是单用户,1.以后进行系统分布需要进行client与server拓展 2.安全性需要做sessionid持久性修改 和用户信息的加密
             HttpServletRequest request = (HttpServletRequest) req;
             HttpServletResponse response = (HttpServletResponse) resp;
             
             //写出request 解决不能多次read的问题 转发时转发myRequestWrapper
             MyRequestWrapper myRequestWrapper = new MyRequestWrapper(request);
             String requestBody = myRequestWrapper.getBody();
             
             JSONObject jsonLogin = JSONObject.parseObject(requestBody);
             if(jsonLogin != null){
                 //剥离登录,不通过cookie login
                 if(jsonLogin.getString("method").equals("CheckLogin") 
                         && jsonLogin.getString("checkValue").equals("mainsoft")){
                     
                    RequestDispatcher requestDispatcher = myRequestWrapper.getRequestDispatcher("/AjaxServlet.do");
                    requestDispatcher.forward(myRequestWrapper, response);
                    
                 }else{
                     
                    //cookie 登录验证,调试时取消控制台注释
                     Cookie cs[] = request.getCookies();
                     
    //               System.out.println("-------app cookie 登录判定开始-------");
                        if (cs != null) {
    //                      System.out.println("<<<<<获取传递cookie:"+JSON.toJSONString(cs));
                            //开始登录
                            Cookie c = cs[0];
                                
    //                          if( c.getMaxAge() > 0 ){//当前cookie未过期
                                    
                                    if(c.getName().equals("userLoginCookie")){
                                        
    //                                  System.out.println("1.cookie 存在,开始进行参数拆分");
                                        //对传递的cookie进行参数拆分  0 ==> username ; 1 ==> userpwd ; 2 ==> sessionid
                                        String arr[] = c.getValue().split(",");
    //                                  System.out.println(JSON.toJSONString(arr));
                                        
                                        //app 使用 cookie 登录
                                        String result = ServiceProxy.indexservice.CheckLogin(arr[0], arr[1]);
    //                                  System.out.println("2.cookie 登录完成,开始验证登录结果");
                                        JSONObject jobj = JSONObject.parseObject(result);
                                            if(jobj.getString("Success") != null
                                                && jobj.getString("Success") != ""
                                                && jobj.getString("Success").equals("true")){
    //                                          System.out.println("3.验证完成,cookie 登录成功,开始对比是否同一浏览器");
                                                
                                                //查询是否同一浏览器
                                                String result1 = ServiceProxy.indexservice.getPWDSessionIDByCode(arr[0]);
                                                if(result1 != null && result1 != ""){
                                                    
    //                                              System.out.println(JSON.toJSONString(result1));
                                                    //验证结果
                                                    JSONObject jobj1 = JSONObject.parseObject(result1);
                                                    if(jobj1.getString("sessionid") != null){
                                                        
                                                        if(!jobj1.getString("sessionid").equals(arr[2])){
                                                            
                                                            //已另一台设备登录 销毁sesion
                                                            if (request.getSession().getAttribute("userLoginSession") != null) {
                                                                request.getSession().invalidate();
                                                            }
                                                            
    //                                                      System.out.println("4.不同浏览器,销毁cookie");
                                                            Cookie cookie = new Cookie("userLoginCookie",c.getValue());
                                                            cookie.setPath(myRequestWrapper.getContextPath());
                                                            cookie.setMaxAge(0);//销毁
                                                            response.addCookie(cookie);
    //                                                      System.out.println("5.写返回信息,另一台设备已经登录");
                                                            renderDefaultJson(response,true);
                                                            
                                                        }else{
                                                            
    //                                                      System.out.println("4.同一浏览器 放行");
                                                            //系统宕机或更新重启,cookie登录对比相同,放行
                                                            chain.doFilter(myRequestWrapper, response);
                                                        }   
                                                    }
                                                    
                                                }
                                                
                                            }else{
    //                                          System.out.println("3.cookie 登录失败");
                                                renderDefaultJson(response,false);
                                            }
    //                              }
                                }else{
    //                              System.out.println("cookie 过期");
                                    renderDefaultJson(response,false);
                                }
                            
    //                      System.out.println("-------app cookie 登录判定结束-------");   
    
                        }else{
                                //cookie 不存在 登录转发
                                RequestDispatcher requestDispatcher = myRequestWrapper.getRequestDispatcher("/AjaxServlet.do");
                                requestDispatcher.forward(myRequestWrapper, response);
                        }
                 }
             }
            
        }
    
        @Override
        public void init(FilterConfig config) throws ServletException {
        }
        
        /**
         * cookie登录异常返回信息
         * @author sxycw
         */
        private void renderDefaultJson(HttpServletResponse response,boolean bool){
            PrintWriter out;
            try {
                out = response.getWriter();
                String jsonResult = null;
                if(bool){
                    jsonResult = "{\"LoginDefault\":\"false\",\"Info\":\"您的账户已在另一设备登录,您已被迫下线!\"}";
                }else{
                    //非写sessionid 都返回重新登录信息
                    jsonResult = "{\"LoginDefault\":\"false\",\"Info\":\"您的登录已过期,请重新登录!\"}";
                }
                out.println(jsonResult);
                out.close(); 
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
    }
    

    2.需要用到的两个工具类,request读流和request存流

    package com.mainsoft.online.util;
    
    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    /**
     * requestwrapepr 
     * @author sxycw
     *
     */
    public class MyRequestWrapper extends HttpServletRequestWrapper{
    
        private String body;
        
        /**
         * 解决request流读一次丢失的问题
         * @param request
         */
        public MyRequestWrapper(HttpServletRequest request) {
            super(request);
            body = RequestUtil.getRequestBody(request);
        }
        
        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
            return new ServletInputStream() {
                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
            };
        }
    
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    
        public String getBody(){
            return body;
        }
    
    }
    
    package com.mainsoft.online.util;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * request工具类
     * @author sxycw
     *
     */
    public class RequestUtil {
    
        /**
         * get request io (json)
         * @author sxycw
         * @param request
         * @return String
         */
        public static String getRequestBody(HttpServletRequest request){
            StringBuilder buffer = new StringBuilder();
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(
                                 new InputStreamReader(request.getInputStream(), "UTF-8"));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (null != reader) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return buffer.toString();
        }   
    }
    

    3.最后添加过滤器到xml入口中

    <!--配置过滤器-->  
      <filter>  
          <filter-name>LoginFilter</filter-name>  
          <filter-class>com.mainsoft.online.sso.LoginFilter</filter-class>  
      </filter>  
      <!--映射过滤器-->  
      <filter-mapping>  
          <filter-name>LoginFilter</filter-name>  
          <!--“/*”表示拦截所有的请求 -->  
          <url-pattern>/*</url-pattern>  
      </filter-mapping>
    

    4.前台使用$.ajax中的dataFilter对参数进行预处理,接收到 logindefault就返回登录页

    -end-

    相关文章

      网友评论

          本文标题:java 单用户登录

          本文链接:https://www.haomeiwen.com/subject/nylicftx.html