java 单用户登录

2018-04-02  本文已影响0人  _Rondo

一、概述

老项目做的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-

上一篇下一篇

猜你喜欢

热点阅读