基於Cookie使用過濾器實現客戶訪問登入功能的詳解

來源:互聯網
上載者:User
這篇文章主要介紹了基於Cookie使用過濾器實現客戶每次訪問只登入一次,需要的朋友可以參考下

相信大家在各大網站都會遇到,登入時,在登入框出現下次免登陸/一個月免登陸的類似選項,本文就是講解如何?,在這記錄一下,也算是做個備忘錄合集,如果文中有錯,歡迎大家指出

為啥說自登陸一次呢,因為當訪問某個頁面時,如果第一次自動登入失敗時,你下次重新整理訪問時還再次走自動登入流程,就會出現死迴圈。

本文程式碼範例架構為Spring MVC,下面就講解實現該功能的需要掌握哪些知識:cookies與過濾器

1.cookies

何為Cookies:Cookies為 Web 應用程式儲存使用者相關資訊提供了一種有用的方法。例如,當使用者訪問您的網站時,您可以利用 Cookie 儲存使用者喜好設定或其他資訊,這樣,當使用者下次再訪問您的網站時,應用程式就可以檢索以前儲存的資訊。

我們看一下是如何儲存cookies和如何刪除cookies

儲存cookies


String newUserName = null;try {  newUserName = URLEncoder.encode(username, "UTF-8");//把使用者名稱轉碼,防止使用者名稱是中文,cookies儲存中文取出會亂碼} catch (UnsupportedEncodingException e) {  e.printStackTrace();}Cookie nameCookie = new Cookie("username", newUserName);String pwdMd5Cook = MD5Util.MD5(Pwd);Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 儲存加密後的密碼nameCookie.setMaxAge(60 * 60 * 24 * 365);// 使用者名稱儲存一年pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密碼儲存30天// 發送Cookie資訊到瀏覽器response.addCookie(nameCookie);response.addCookie(pwdCookie);

刪除cookies,刪除很簡單,但值得注意的時,刪除cookies,跟儲存cookies一定要在同一個控制層,不然會找不到儲存的cookies,導致刪除不了


Cookie cookie = new Cookie("pwd", null);cookie.setMaxAge(0);// 刪除密碼cookieresponse.addCookie(cookie);

2.Filter-過濾器

Filter也稱之為過濾器,它是Servlet技術中最實用的技術,Web開發人員通過Filter技術,對web伺服器管理的所有web資源:例如Jsp, Servlet, 靜態圖片檔案或靜態 html 檔案等進行攔截,從而實現一些特殊的功能。例如實現URL層級的許可權存取控制、過濾禁用語、壓縮響應資訊等一些進階功能。

實現方法:繼承Filter介面,並實現其doFilter方法。在web.xml檔案中對編寫的filter類進行註冊,並設定它所能攔截的資源


<filter>指定一個過濾器。<filter-name>用於為過濾器指定一個名字,該元素的內容不可為空。<filter-class>元素用於指定過濾器的完整的限定類名。<init-param>元素用於為過濾器指定初始化參數,它的子項目<param-name>指定參數的名字,<param-value>指定參數的值。在過濾器中,可以使用FilterConfig介面對象來訪問初始化參數。<filter-mapping>元素用於設定一個 Filter 所負責攔截的資源。一個Filter攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑<filter-name>子項目用於設定filter的註冊名稱。該值必須是在<filter>元素中聲明過的過濾器的名字<url-pattern>設定 filter 所攔截的請求路徑(過濾器關聯的URL樣式)<servlet-name>指定過濾器所攔截的Servlet名稱。<filter>  <filter-name>suicaiFilter</filter-name>  <filter-class>com.suicai.filter.suicaiFilter</filter-class></filter><filter-mapping>  <filter-name>suicaiFilter</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>

下面看一下實際應用代碼:


public class suicaiFilter implements Filter {  @Override  public void destroy() {  }  @Override  public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {    HttpServletRequest req=(HttpServletRequest)request;    HttpServletResponse res=(HttpServletResponse)response;    HttpSession session = req.getSession();    String requestURI = req.getRequestURI();    String param = req.getQueryString();    String url = req.getServletPath();    if(param!=null){      url = url+"?"+param;    }    if(requestURI.contains("js") || requestURI.contains("css") || requestURI.contains("images")){      //不過濾css,js,images等靜態資源      chain.doFilter(request, response);    }else if(requestURI.contains("/info/")||requestURI.contains("/gys/")){      //過濾前台訪問頁面,跟前台個人中心(供應商後台),自動登入一次,登入不成功不進行操作,個人中心登入不成功,則跳到登入頁面      ProviderInfo providerInfo = (ProviderInfo) session.getAttribute("providerInfo_gys");      String IsAutomaticLogin = (String) session.getAttribute("IsAutomaticLogin");//是否已經走過自動登入流程標識      if(requestURI.contains("/info/") && !requestURI.contains("/login")){        //訪問門戶等不需要必須登入的(登入除外),只嘗試登入一次,如果不成功,不進行操作        if(providerInfo==null && IsAutomaticLogin == null){          req.getSession().setAttribute("goURL", url);          res.sendRedirect(req.getContextPath() + "/common/automaticLogin");        }else if(providerInfo==null && IsAutomaticLogin != null ){          chain.doFilter(request, response);        }else{          chain.doFilter(request, response);        }      }else if(requestURI.contains("/gys/")){//訪問個人中心,自登陸一次,不成功跳轉到登入頁面        if(providerInfo==null && IsAutomaticLogin == null){          req.getSession().setAttribute("goURL", url);          res.sendRedirect(req.getContextPath() + "/common/automaticLogin");        }else if(providerInfo==null && IsAutomaticLogin != null ){          session.setAttribute("redirectUrl", url);          res.sendRedirect(req.getContextPath() + "/login.jsp?redirectUrl="+url);        }else{          chain.doFilter(request, response);        }      }else{        chain.doFilter(request, response);      }    }else{      //不過濾      chain.doFilter(request, response);    }  }  @Override  public void init(FilterConfig arg0) throws ServletException {  }}

從代碼中可知,需要一個是否已經自動登入過的標識(IsAutomaticLogin),該標識是在走自動登入時(不管成不成功)儲存起來的

3.結合上面提供知識,下面為整體代碼展示,如發現不對地方,歡迎大家指出


@Controller@RequestMapping("/common")public class CommonController{  /**   * 自動登入方法   * @param request   * @param response   * @param username   * @param pwd   * @param ProviderInfo 供應商賬戶資訊model   * @return   */  @RequestMapping("/automaticLogin")  public String automaticLogin(HttpServletRequest request,ServletResponse response,@CookieValue(value = "username", required = false) String username,@CookieValue(value = "pwd", required = false) String pwd,ProviderInfo ProviderInfo) {    // 儲存需求登入前的連結    String goURL = (String) session.getAttribute("goURL");    if (username == null) {//cookies中沒有使用者名稱,肯定不需要自動登入      session.setAttribute("IsAutomaticLogin", "0");      return "redirect:" + goURL;    } else {      try {        username = URLDecoder.decode(username, "UTF-8");//轉義,防止中文      } catch (UnsupportedEncodingException e) {        e.printStackTrace();      }    }    // cookie失效 session一定為空白,因為登入時,一定會把使用者名稱儲存在cookie中    if ("".equals(username) || username == null) {// 使用session登入不了,不進行任何操作,不在進入這個方法      session.setAttribute("IsAutomaticLogin", "0");      return "redirect:" + goURL;    } else {      // cookie中沒有密碼,判斷session為不為空白,如果為空白,說明沒有登入,如果不為空白,說明,使用者是選擇不記住密碼登入(所以cookie中沒有密碼)      if ("".equals(pwd) || pwd == null) {        ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");        if (customer1 == null) {// 使用session登入不了,不進行任何操作,不在進入這個方法          session.setAttribute("IsAutomaticLogin", "0");          return "redirect:" + goURL;        } else {          // 已經登入,不再進入這個方法          return "redirect:" + goURL;        }      } else {        // cookie中有密碼,判斷session為不為空白,如果為空白,說明沒有登入,如果不為空白,說明已經登入        ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");        if (customer1 == null) {// 當前沒有登入,調用cookies中的使用者名稱跟密碼進行登入          // 進行自動登入操作,登入成功後返回原來頁面          ProviderInfo customer3 = ValidateDate(username);          customer3.setPwd(pwd);          customer3.setAccountType(6);          ProviderInfo customer2 = infoService.login(customer3);//調用登入方法          if (customer2 == null) {// 自動登入失敗,不再進入這個方法            session.setAttribute("IsAutomaticLogin", "0");            return "redirect:" + goURL;          } else {            // 登陸成功儲存客戶資訊到session            session.setAttribute("providerInfo_gys",customer2);            return "redirect:" + goURL;          }        } else {          return "redirect:" + goURL;        }      }    }  }  /**   * 使用者登陸   * @param request   * @param response   * @param cus   * @return   */  @RequestMapping("/UserLogin")  @ResponseBody  public Map<String, Object> goLogin(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("ProviderInfo") ProviderInfo cus) {    /*省略一些邏輯判斷*/    cus.setPwd(MD5Util.MD5(Pwd));    ProviderInfo providerInfo = infoService.login(cus);    Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();    if (providerInfo == null) {      // 登陸失敗,重新跳轉到登陸頁面      map.put("error", "密碼錯誤");      return map;    }else{      String newUserName = null;      if (remember_me.equals("1")) {// 有選擇一個月免登入        try {          newUserName = URLEncoder.encode(username, "UTF-8");        } catch (UnsupportedEncodingException e) {          e.printStackTrace();        }        Cookie nameCookie = new Cookie("username", newUserName);        String pwdMd5Cook = MD5Util.MD5(Pwd);        Cookie pwdCookie = new Cookie("pwd", pwdMd5Cook);// 儲存加密後的密碼+"create"        nameCookie.setMaxAge(60 * 60 * 24 * 365);// 使用者名稱儲存一年        pwdCookie.setMaxAge(60 * 60 * 24 * 30);// 密碼儲存30天        // 發送Cookie資訊到瀏覽器        response.addCookie(nameCookie);        response.addCookie(pwdCookie);        session.setAttribute("IsAutomaticLogin",null);      }else{//沒有選擇,刪除上次可能已經選擇自動登入時的密碼        Cookie[] cookies = request.getCookies();        if (null != cookies) {          for (Cookie cookie : cookies) {            cookieMap.put(cookie.getName(), cookie);          }        }        if (cookies != null) {          for (int i = 0; i < cookies.length; i++) {            if (cookieMap.containsKey("pwd")) {              Cookie cookie = new Cookie("pwd", null);              cookie.setMaxAge(0);// 刪除密碼cookie              response.addCookie(cookie);            }          }        }      }      // 登陸成功,儲存當前user資訊,儲存客戶資訊到session      map.put("ProviderInfo", providerInfo);      map.put("goURL", session.getAttribute("goURL"));      session.setAttribute("providerInfo_gys", providerInfo);      return map;    }else {      map.put("error", "該供應商帳號不存在");      return map;    }  }  /**   * 登出   * @return   */  @RequestMapping("/logout")  public String logout(HttpServletResponse response) {    Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();    Cookie[] cookies = request.getCookies();    if (null != cookies) {      for (Cookie cookie : cookies) {        cookieMap.put(cookie.getName(), cookie);      }    }    if (cookies != null) {      for (int i = 0; i < cookies.length; i++) {        if (cookieMap.containsKey("pwd")) {          Cookie cookie = new Cookie("pwd", null);          cookie.setMaxAge(0);// 刪除密碼cookie          response.addCookie(cookie);        }      }    }    session.setAttribute("providerInfo_gys", null);    return "/index";  }}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.