如果用户是在自己家的电脑上上网,登录时就可以记住他的登录信息,下次访问时不需要再次登录,直接访问即可。实现方法是把登录信息如账号、密码等保存在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 <% } %>
















