自動登錄問題和MD5加密
前面已經完成了Filter的自動登錄,但是有問題,我們在web.xml中Filter的url-mapping中配置的規則是/*, 也就是這個網站的所有請求都攔截。這肯定不合適。我們本來訪問/login.jsp,本來就是去登錄,結果也進行了攔截。
解決自動登錄問題
其實,我們可以在AutoLoginFilter.java這個文件中寫if語句來判斷,雖然web.xml文件還是配置攔截/*, 但是只有在if滿足條件,才進行攔截,否則,直接放行就好。
下面if條件,我們不希望/login.jsp 和/loginServlet這兩個請求地址被攔截,所以這裡取反,使用!符號。意思就是除了這兩個之外地址都攔截。
package com.kaigejava.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.anthony.domain.User;
import com.anthony.service.UserService;
import com.anthony.service.UserServiceImpl;
public class AutoLoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 1 轉換兩個對象 HttpServletRequest HttpServletResponse
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// 優化
String uri = req.getRequestURI(); // 瀏覽器中url埠8080後面部分
String path = req.getContextPath(); // 應用名稱
path = uri.substring(path.length()); // /login.jsp
if (!("/login.jsp".equals(path)) || ("/loginServlet".equals(path))) {
// 2.處理業務, 這裡是得到cookies
// 優化
User user = (User) req.getSession().getAttribute("user");
if (user == null) { // 說明從來沒有登錄過
Cookie[] cookies = req.getCookies();
String username = "";
String password = "";
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("user".equals(cookies[i].getName())) {
String value = cookies[i].getValue(); // username&password這樣一個格式字符串
// 得到用戶名和密碼
String[] values = value.split("&");
username = values[0];
password = values[1];
}
}
UserService us = new UserServiceImpl();
User u = us.findUser(username, password);
if (u != null) { // 如果登錄成功,把用戶信息存到session中
req.getSession().setAttribute("user", u);
}
}
}
// 3.放行
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
可以再次測試下,例如在LoginServlet中或者列印用戶名和密碼欄位,可以發現只執行了一次登錄,也就是沒有被攔截。
MD5加密
第一個要知道的是MD5(Message-Digest Algoorithm 5)是一種不可逆的加密算法。也就是只能加密,不能解密操作。那麼我們登錄是如何做到呢,一般來說資料庫中用戶名密碼肯定採用MD5加密。在後臺拿到前端獲取密碼,然後把這個密碼通過MD5加密,然後傳入資料庫和密碼這欄比較,相等就說明密碼一樣。
先來看看MD5加密效果
上面這個圖是用戶密碼在資料庫中是沒有加密過的,下面我們執行把第二個用戶進行md5加密之後,看看加密之後密碼處的效果。
UPDATE users SET PASSWORD=MD5(PASSWORD) WHERE id=2;
這個一長串密碼就是MD5加密之後的效果。
Java中如何使用MD5加密
這個MD5加密方法算一個工具類吧,網上很容易搜到,下面是代碼方法
package com.anthony.util;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
public static String md5(String plainText) {
byte[] secreBytes = null;
try {
secreBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
}catch (NoSuchAlgorithmException e) {
throw new RuntimeException("沒有md5這個算法!");
}
String md5code = new BigInteger(1, secreBytes).toString(16);
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
}
登錄過程使用加密密碼在LoginServlet.java中處理登錄,這個我們通過request.getParameter(「password」)得到的密碼肯定是明文的,這時候我們需要先給password進行MD5加密,然後進行登錄操作。(前提是用戶註冊過程中,後臺代碼在處理註冊的servlet中就把用戶密碼給進行MD5加密,然後保存在數據中的密碼就是加密的形式)
上面如果是在註冊的servlet中也這樣對password進行加密。