使用Cookie并使用MD5算法实现用户永久登录
2016-02-12 03:23
357 查看
如果用户是在自己家的电脑上网,登录时就可以记住他的登录信息,下次访问的时不需要再次登录,直接访问即可。实现方法就是把登录信息如账号信息如账号、密码等保存在Cookie中,并控制Cookie的有效期,下次访问时在验证Cookie中的登录信息即可。
保存登录信息有多重方案。最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中。
还有一种方案是把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。这种方案略微安全一些。如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。
这几种方案验证账号时都要查询数据库。本例将采用另一种方案,只在登录时查询一次数据库,以后访问验证登录信息时不再查询数据库。实现方式是把账号按照一定的规则加密后,连同账号一块保存到Cookie中。下次访问时只需要判断账号的加密规则是否正确即可。下面例子把账号保存到名为accountt的Cookie中,把账号连同秘钥用MD5算法加密后保存到名为ssid的Cookie中。验证时验证Cookie的账号与密钥加密后是否与Cookie中的ssid相等。代码如下:
loginCookie.jsp
登录时可以选择登录信息的有效期:关闭浏览器即失效、30天内有效与永久失效。通过设置Cookie的maxAge属性来实现。运行效果如下:
![](http://img.blog.csdn.net/20160212032242692)
保存登录信息有多重方案。最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中。
还有一种方案是把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。这种方案略微安全一些。如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。
这几种方案验证账号时都要查询数据库。本例将采用另一种方案,只在登录时查询一次数据库,以后访问验证登录信息时不再查询数据库。实现方式是把账号按照一定的规则加密后,连同账号一块保存到Cookie中。下次访问时只需要判断账号的加密规则是否正确即可。下面例子把账号保存到名为accountt的Cookie中,把账号连同秘钥用MD5算法加密后保存到名为ssid的Cookie中。验证时验证Cookie的账号与密钥加密后是否与Cookie中的ssid相等。代码如下:
loginCookie.jsp
<%@ page language="java" pageEncoding="UTF-8" isErrorPage="false" %> <jsp:directive.page import="java.security.MessageDigest"/> <%! // 密钥 private static final String KEY = ":cookie@helloweenvsfei.com"; // MD5 加密算法 public final static String calcMD5(String ss) { String s = ss==null ? "" : ss; char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; try { byte[] strTemp = s.getBytes(); MessageDigest mdTemp = MessageDigest.getInstance("MD5"); mdTemp.update(strTemp); byte[] md = mdTemp.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { return null; } } %> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); String action = request.getParameter("action"); if("login".equals(action)){ String account = request.getParameter("account"); String password = request.getParameter("password"); int timeout = new Integer(request.getParameter("timeout")); // 把帐号连同密钥使用MD5后加密后保存 String ssid = calcMD5(account + KEY); // 把帐号保存到Cookie中 并控制有效期 Cookie accountCookie = new Cookie("account", account); accountCookie.setMaxAge(timeout); // 把加密结果保存到Cookie中 并控制有效期 Cookie ssidCookie = new Cookie("ssid", ssid); ssidCookie.setMaxAge(timeout); response.addCookie(accountCookie); response.addCookie(ssidCookie); // 重新请求本页面 response.sendRedirect(request.getRequestURI() + "?" + System.currentTimeMillis()); return; } else if("logout".equals(action)){ // 删除Cookie中的帐号 Cookie accountCookie = new Cookie("account", ""); accountCookie.setMaxAge(0); // 删除Cookie中的加密结果 Cookie ssidCookie = new Cookie("ssid", ""); ssidCookie.setMaxAge(0); response.addCookie(accountCookie); response.addCookie(ssidCookie); // 重新请求本页面 response.sendRedirect(request.getRequestURI() + "?" + System.currentTimeMillis()); return; } boolean loggin = false; String account = null; String ssid = null; // 获取Cookie中的account与ssid if(request.getCookies() != null){ for(Cookie cookie : request.getCookies()){ if(cookie.getName().equals("account")) account = cookie.getValue(); if(cookie.getName().equals("ssid")) ssid = cookie.getValue(); } } if(account != null && ssid != null){ // 如果加密规则正确, 则视为已经登录 loggin = ssid.equals(calcMD5(account + KEY)); } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><%= loggin ? "欢迎您回来" : "请先登录" %></title> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <div align="center" style="margin:10px; "> <fieldset> <legend>当前有效的 Cookie</legend> <script>document.write(document.cookie);</script> </fieldset> <fieldset> <legend><%= loggin ? "欢迎您回来" : "请先登录" %></legend> <% if(loggin){ %> 欢迎您, ${ cookie.account.value }. <a href="${ pageContext.request.requestURI }?action=logout">注销</a> <% } else { %> <form action="${ pageContext.request.requestURI }?action=login" method="post"> <table> <tr> <td> 帐号: </td> <td> <input type="text" name="account" style="width:200px; "> </td> </tr> <tr> <td> 密码: </td> <td> <input type="password" name="password" style="width:200px; "> </td> </tr> <tr> <td> 有效期: </td> <td> <input type="radio" name="timeout" value="-1" checked> 关闭浏览器即失效 <br/> <input type="radio" name="timeout" value="<%= 30 * 24 * 60 * 60 %>"> 30天内有效 <br/> <input type="radio" name="timeout" value="<%= Integer.MAX_VALUE %>"> 永久有效 <br/> </td> </tr> <tr> <td> </td> <td> <input type="submit" value=" 登 录 " class="button"> </td> </tr> </table> </form> <% } %> </fieldset> </div> </body> </html>
登录时可以选择登录信息的有效期:关闭浏览器即失效、30天内有效与永久失效。通过设置Cookie的maxAge属性来实现。运行效果如下:
相关文章推荐
- PLC多种编程方法例举
- 无符号数相减问题 C语言
- Android开发常用的36个代码片段
- [Redux] Generating Containers with connect() from React Redux (FooterLink)
- 程序员必须注意的十大编程禁忌
- HDU 1016 Prime Ring Problem(DFS)
- Linux 学习树之基础20160212
- 提升Python编程效率的10点建议
- 小白自学敲代码的零散知识点整理
- [Redux] Generating Containers with connect() from React Redux (AddTodo)
- tkinter界面卡死的解决办法
- day16-----------集合框架
- 【CodeForces 618B】Guess the Permutation
- Asymptotic notation
- TCP/IP协议模型详解
- 【CodeForces 624C】Graph and String
- apache commons io 2.2(五)Output部分
- HDU 1241 Oil Deposits(DFS模板题)
- WC2016总结
- hdoj 1394 Minimum Inversion Number(树状数组求逆序对)