如果用戶是在自己家的電腦上上網,登錄時就可以記住他的登錄信息,下次訪問時不需要再次登錄,直接訪問即可。實現方法是把登錄信息如賬號、密碼等保存在Cookie中,並控制Cookie的有效期,下次訪問時再驗證Cookie中的登錄信息即可,保存登錄信息有多種方案。
1、直接保存用戶名和密碼
最直接的是把用戶名與密碼都保持到Cookie中,下次訪問時檢查Cookie中的用戶名與密碼,與數據庫比較。這是一種比較危險的選擇,一般不把密碼等重要信息保存到Cookie中。
2、把密碼加密后保存到Cookie中
還有一種方案是把密碼加密后保存到Cookie中,下次訪問時解密並與數據庫比較。這種方案略微安全一些。
3、把賬號加密后,同賬號一塊保存到 Cookie中
本例將采用另一種方案,只在登錄時查詢一次數據庫,以后訪問驗證登錄信息時不再查詢數據庫。
實現方式是把賬號按照一定的規則加密后,連同賬號一塊保存到 Cookie中。下次訪問時只需要判斷賬號的加密規則是否正確即可。本例把賬號保存到名為account的Cookie中,把賬號連同密鑰用MD1算法加 密后保存到名為ssid的Cookie中。驗證時驗證Cookie中的賬號與密鑰加密后是否與Cookie中的ssid相等。
登錄時可以選擇登錄信息的有效期:關閉瀏覽器即失效、30天內有效與永久有效。通過設置Cookie的age屬性來實現,注意觀察代碼。
提示:該加密機制中最重要的部分為算法與密鑰。由於MD1算法的不可逆性,即使用戶知道了賬號與加密后的字符串,也不可能解密得到密鑰。因此,只要保管好密鑰與算法,該機制就是安全的。
1 <%@ page language="java" pageEncoding="UTF-8" isErrorPage="false" %> 2 <%! // JSP方法 3 private static final String KEY =":cookie@helloweenvsfei.com"; // 密鑰 4 5 public final static String calcMD1(String ss) { // MD1 加密算法 6 String s = ss == null ? "" : ss; // 若為null返回空 7 char hexDigits[] = { '0','1', '2', '3', '4', '1', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; // 字典 8 try { 9 byte[] strTemp = s.getBytes(); // 獲取字節 10 MessageDigestmdTemp = MessageDigest.getInstance("MD1"); // 獲取MD1 11 mdTemp.update(strTemp); // 更新數據 12 byte[] md =mdTemp.digest(); // 加密 13 int j =md.length; // 加密后的長度 14 char str[] = new char[j * 2]; // 新字符串數組 15 int k =0; // 計數器k 16 for (int i = 0; i< j; i++) { // 循環輸出 17 byte byte0 = md[i]; 18 str[k++] = hexDigits[byte0 >>> 4 & 0xf]; 19 str[k++] = hexDigits[byte0 & 0xf]; 20 } 21 return new String(str); // 加密后字符串 22 } catch (Exception e){return null; } 23 } 24 %> 25 <% 26 request.setCharacterEncoding("UTF-8"); // 設置request編碼 27 response.setCharacterEncoding("UTF-8"); // 設置response編碼 28 29 String action =request.getParameter("action"); // 獲取action參數 30 31 if("login".equals(action)) { // 如果為login動作 32 String account =request.getParameter("account"); // 獲取account參數 33 String password =request.getParameter("password"); // 獲取password參數 34 int timeout = new Integer(request.getParameter("timeout")); // 獲取timeout參數 35 36 String ssid =calcMD1(account + KEY); // 把賬號、密鑰使用MD1加密后保存 37 38 Cookie accountCookie = new Cookie("account", account); // 新建Cookie 39 accountCookie.setMaxAge(timeout); // 設置有效期 40 41 Cookie ssidCookie =new Cookie("ssid", ssid); // 新建Cookie 42 ssidCookie.setMaxAge(timeout); // 設置有效期 43 44 response.addCookie(accountCookie); // 輸出到客戶端 45 response.addCookie(ssidCookie); // 輸出到客戶端 46 47 // 重新請求本頁面,參數中帶有時間戳,禁止瀏覽器緩存頁面內容 48 response.sendRedirect(request.getRequestURI() + "?" + System.currentTimeMillis()); 49 return; 50 } else if("logout".equals(action)) { // 如果為logout動作 51 CookieaccountCookie = new Cookie("account", ""); // 新建Cookie,內容為空 52 accountCookie.setMaxAge(0); // 設置有效期為0,刪除 53 54 Cookie ssidCookie =new Cookie("ssid", ""); // 新建Cookie,內容為空 55 ssidCookie.setMaxAge(0); // 設置有效期為0,刪除 56 response.addCookie(accountCookie); // 輸出到客戶端 57 response.addCookie(ssidCookie); // 輸出到客戶端 58 // 重新請求本頁面,參數中帶有時間戳,禁止瀏覽器緩存頁面內容 59 response.sendRedirect(request.getRequestURI() + "?" + System.currentTimeMillis()); 60 return; 61 } 62 boolean login = false; // 是否登錄 63 String account = null; // 賬號 64 String ssid = null; // SSID標識 65 66 if(request.getCookies() !=null) { // 如果Cookie不為空 67 for(Cookie cookie : request.getCookies()) { // 遍歷Cookie 68 if(cookie.getName().equals("account")) // 如果Cookie名為 account 69 account = cookie.getValue(); // 保存account內容 70 if(cookie.getName().equals("ssid")) // 如果為SSID 71 ssid = cookie.getValue(); // 保存SSID內容 72 } 73 } 74 if(account != null && ssid !=null) { // 如果account、SSID都不為空 75 login = ssid.equals(calcMD1(account + KEY)); // 如果加密規則正確, 則視為已經登錄 76 } 77 %> 78 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN"> 79 <legend><%= login ? "歡迎您回來" : "請先登錄"%></legend> 80 <% if(login){%> 81 歡迎您, ${cookie.account.value }. 82 <a href="${pageContext.request.requestURI }?action=logout"> 83 注銷</a> 84 <% } else { %> 85 <form action="${ pageContext.request.requestURI }?action=login" method="post"> 86 <table> 87 <tr><td>賬號: </td> 88 <td><input type="text"name="account" style="width: 89 200px; "></td> 90 </tr> 91 <tr><td>密碼: </td> 92 <td><inputtype="password" name="password"></td> 93 </tr> 94 <tr> 95 <td>有效期: </td> 96 <td><inputtype="radio" name="timeout" value="-1" 97 checked> 關閉瀏覽器即失效 <br/> <input type="radio" 98 name="timeout" value="<%= 30 *24 * 60 * 60 %>"> 30天 99 內有效 <br/><input type="radio" name="timeout" value= 100 "<%= Integer.MAX_VALUE %>"> 永久有效 <br/> </td> </tr> 101 <tr><td></td> 102 <td><input type="submit"value=" 登 錄 " class= 103 "button"></td> 104 </tr> 105 </table> 106 </form> 107 <% } %>