這篇文章主要介紹了基於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"; }}