Filter應用之-自動登錄
自動登錄,是為了幫助用戶多次使用這個網頁時,不用再次輸入用戶名和密碼就可以登錄。
是指用戶將用戶的登錄信息,人,保存到本地的文件中Cookie中。
Name,value – 聲明時 new Cookie(key,value);
Path - 默認值,即為當前保存cookie的這個serlvet所在的路徑。
如果Cookie在這樣的路徑:http://loclhost:8080/project/abc/AServlet
則Cookie的路徑為: http://loclhost/project/abc
則說明:
所在在http://loclhost/project/abc目錄下的servlet才可以讀取這個cookie的值。
如果:
保存Cookie類:http://loclhost:8080/project/a/b/AServlet
則Cookie的默認path為;
http://loclhost/project/a/b
對於path這個值可以手工設置:
如果設置為: http://loclhost/project/ 即到項目名。
則所有這個項目中的所有Serlvet|jsp都可以讀取到這個 cookie.
Cookie.setPath(requst.getContextPath());
如果將path設置為 /
即:cookie.setpath(“/”); - http://localhost/
則所有在tomcat中運行的項目都可以讀取這個到cookie.
如果path設置為/必須要與domain共同使用才有意義。
Age - 默認值-1,在瀏覽器中存在。 0:刪除文件中的cookie和瀏覽器中的cookie。
Domain - 域 -
www.sina.com - login
www.bbs.sina.com
www.news.sina.com
刪除時,必須要設置的與之前設置的信息完全一樣:
Name
Age = 0(文件和緩存),-1(只刪除文件)
Path 一樣。
Domain :null
下一次用戶再打開這個網頁時,應該讀取cookie中的信息,實現自動登錄。
思路:登錄時用戶勾選了記住密碼幾天,登錄Servlet 裏返回給瀏覽器一個Cookie,name是autoLogin,value是:(編碼)用戶名_(加密)密碼,用戶再次進來時,過濾器遍歷所有的Cookie,看是否有一個叫autoLgin的Cookie。如果有,解析用戶名密碼。自動登錄。其中加密部分借鑒了別人的文章感覺不錯。連接。
代碼L:
User類:
package com.lhy.domain; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
LoginServlet:
@WebServlet(name="LoginServlet",urlPatterns="/LoginServlet") public class LoginServlet extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.err.println("---------->LoginServlet"); req.setCharacterEncoding("UTF-8"); // String username = req.getParameter("username"); String password = req.getParameter("password"); //是否自動登錄 String auto = req.getParameter("auto"); if("lhy".equals(username) && "123".equals(password)){ //登錄成功,將用戶信息放session User user = new User(); user.setUsername(username); req.getSession().setAttribute("user", user); if(!"-1".equals(auto)){ //勾選了自動登錄 int day = Integer.parseInt(auto);//1|7 int seconds = 60 * 60 * 24 * day;//cookie存活時間 單位:秒 //聲明cookie // 用戶名(編碼)_密碼(加密)) //cookie不能存中文,用戶名有中文編碼後可以轉為字母 Cookie c = new Cookie("autoLogin",Base64Util.encode(username)+"_"+Md5Util.encode(password)); c.setMaxAge(seconds); c.setPath(req.getContextPath()); //保存cookie resp.addCookie(c); resp.sendRedirect(req.getContextPath()+"/jsps/main.jsp"); } }else{ //登錄失敗 req.getSession().setAttribute("msg", "用戶名或密碼錯誤"); resp.sendRedirect(req.getContextPath()+"/index.jsp"); } } }
LogoutServlet:
@WebServlet(name="LogoutServlet",urlPatterns="/LogoutServlet") public class LogoutServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.err.println("用戶退出"); //刪除整個session req.getSession().invalidate(); Cookie c = new Cookie("autoLogin","ddd"); c.setMaxAge(0); c.setPath(req.getContextPath()); resp.addCookie(c); //用戶退出動作的標識 req.getSession().setAttribute("exit",true); resp.sendRedirect(req.getContextPath()+"/index.jsp"); } }
過濾器:
public class AutoLoginFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 在這兒讀取cookie HttpServletRequest req = (HttpServletRequest)request; // 獲取用戶請求的uri String uri = req.getRequestURI();//AutoLogin/index.jsp //1.對於登錄、退出,直接放行 if(req.getSession().getAttribute("exit")==null){ //退出過來的 if(req.getSession().getAttribute("user")==null){ if(!uri.endsWith("index.jsp")){ //獲取所有的cookie Cookie[] cookies = req.getCookies(); if(cookies != null){ for (Cookie cookie : cookies) { if(cookie.getName().equals("autoLogin")){//如果存在自動登錄的cookie String usernameAndPassword = cookie.getValue();//用戶名密碼 base64username_md5password String username = usernameAndPassword.split("_")[0];//base64用戶名 String password = usernameAndPassword.split("_")[1];//md5密碼 //解碼用戶名 username = Base64Util.decode(username); //根據用戶名查詢,這裏模擬。123的md5:ICy5YqxZB1uWSwcVLSNLcA== if("lhy".equals(username) && "ICy5YqxZB1uWSwcVLSNLcA==".equals(password)){ //登錄成功 User u = new User(); u.setUsername(username); req.getSession().setAttribute("user", u); break ; } } } } } } }else{ //退出過來的,清除session裏exit req.getSession().removeAttribute("exit"); } //不管是否自動登錄成 chain.doFilter(request, response); } @Override public void destroy() { } }
編碼加密工具類:
public class Base64Util { //編碼 中文 -------------5Lit5paH public static String encode(String str){ BASE64Encoder b64= new BASE64Encoder(); return b64.encode(str.getBytes()); } //解碼 5Lit5paH----中文 public static String decode(String str){ try { BASE64Decoder b64decoder = new BASE64Decoder(); byte [] afterStr = b64decoder.decodeBuffer(str); return new String(afterStr); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } public void testEncode(){ } public static void main(String[] args) { String str = Base64Util.encode("中文"); System.out.println(str); String newString = Base64Util.decode(str); System.out.println(newString); } }
public class Md5Util { //md5加密的方法 public static String encode(String old){ try { MessageDigest md5 = MessageDigest.getInstance("md5"); byte newStr[] = md5.digest(old.getBytes()); BASE64Encoder b64= new BASE64Encoder(); return b64.encode(newStr); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); throw new RuntimeException(e); } } public static void main(String[] args) { String s = Md5Util.encode("123"); System.err.println(s);//ICy5YqxZB1uWSwcVLSNLcA== } }
用到了 jar包:sun.misc.BASE64Decoder.jar
過濾器配置:
<filter> <filter-name>autoLogin</filter-name> <filter-class>com.lhy.filter.AutoLoginFilter</filter-class> </filter> <filter-mapping> <filter-name>autoLogin</filter-name> <!-- <url-pattern>*.jsp</url-pattern> --> <url-pattern>/*</url-pattern> </filter-mapping>
登錄表單:
<body> <c:if test="${not empty sessionScope.msg}"> <font color="red"> ${sessionScope.msg} </font> <c:remove var="msg" scope="session"/> </c:if> <form name="x" method="post" action="<c:url value=‘/LoginServlet‘/>"> Name:<input type="text" name="username"/><br/> Password:<input type="password" name="password"/><br/> auto:<input type="radio" name="auto" value="-1">不自動登錄 <br/> <input type="radio" name="auto" value="1">1天<br/> <input type="radio" name="auto" value="7">1周<br/> <input type="submit"/> </form> </body>
main.jsp:
<body> 這是首頁,歡迎你:${user.username} | <a href="LogoutServlet">退出</a> </body>
只是記錄下學習到這個知識點,解決這個問題的思路,肯定還不完善,有錯誤清指出!謝謝!
Filter應用之-自動登錄