做網站前端使用者登入時需要有個下次自動登入的功能。看了看各大網站都有這種功能。
問題描述:使用者登入網站時,一般有個checkbox讓使用者選擇是否可以下次自動登入。選擇後,即使使用者關閉浏覽器,下次再通路這個網站時直接就登入了,不需要使用者名和密碼。
主要使用cookie。cookie是web伺服器存放在用戶端的一個檔案,主要用來記錄使用者浏覽網站資訊的。它主要有兩個功能:一個是記錄使用者資訊,下次自動登入的。另一個是記錄跟蹤統計使用者浏覽網頁的習慣(浏覽過哪些網站?停留時間,利用這個可以做通路量統計),我們主要用到第一個功能。配合代碼講解:
核心類:UserCookieUtil
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import net.cloudsun.base.entity.User;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class UserCookieUtil {
// 儲存cookie的cookieName
private final static String cookieDomainName = "項目名"; //自己随便定義
// 加密cookie時的網站自定碼
private final static String webKey = "項目名"; //自己随便定義
// 設定cookie有效期是兩個星期,根據需要自定義
private final static long cookieMaxAge = * * * * ;
// 儲存Cookie到用戶端
// 傳遞進來的user對象中封裝了在登陸時填寫的使用者名與密碼
public static void saveCookie(User user, HttpServletResponse response) {
// cookie的有效期至(到哪一天)
long validTime = System.currentTimeMillis() + (cookieMaxAge * );
// MD5加密使用者詳細資訊(其實就是把目前使用者加密一下,後面判斷是否是同一個使用者)
String cookieValueWithMd5 = getMD5(user.getUserName() + ":"+ user.getPassWord() + ":" + validTime + ":" + webKey);
// 将要被儲存的完整的Cookie值
String cookieValue = user.getUserName() + ":" + validTime +":"+cookieValueWithMd5;
// 再一次對Cookie的值進行BASE64編碼
String cookieValueBase64 = new String(Base64.encode(cookieValue.getBytes()));
// 開始儲存Cookie(cookie是網站名和值)
Cookie cookie = new Cookie(cookieDomainName, cookieValueBase64);
// 存兩年(這個值應該大于或等于validTime)
cookie.setMaxAge( * * * * );
// cookie有效路徑是網站根目錄
cookie.setPath("/");
// 向用戶端寫入
response.addCookie(cookie);
}
// 使用者登出時,清除Cookie
public static void clearCookie(HttpServletResponse response) {
//建立一個空cookie添加,覆寫原來的達到清除目的
Cookie cookie = new Cookie(cookieDomainName, null);
cookie.setMaxAge();
cookie.setPath("/");
response.addCookie(cookie);
}
// 擷取Cookie組合字元串的MD5碼的字元串
public static String getMD5(String value) {
String result = null;
try {
byte[] valueByte = value.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(valueByte);
result = toHex(md.digest());
} catch (NoSuchAlgorithmException e2) {
e2.printStackTrace();
}
return result;
}
// 将傳遞進來的位元組數組轉換成十六進制的字元串形式并傳回
private static String toHex(byte[] buffer) {
StringBuffer sb = new StringBuffer(buffer.length * );
for (int i = ; i < buffer.length; i++) {
sb.append(Character.forDigit((buffer[i] & ) >> , ));
sb.append(Character.forDigit(buffer[i] & , ));
}
return sb.toString();
}
}
在使用者登入的方法裡儲存cookie值。等使用者選中下次自動登入并且本次登入成功後調用一下上面類的儲存方法。
下次當使用者在通路該網站時可以用攔截器(我用的是攔截器)攔截路徑判斷一下cookie是否存有該網站的user對象:有就自動登入。
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.cloudsun.base.entity.User;
import net.cloudsun.base.service.UserService;
import net.cloudsun.util.UserCookieUtil;
import net.cloudsun.util.WebKeys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.itextpdf.text.pdf.codec.Base64;
public class PowerInterceptor extends HandlerInterceptorAdapter{
private final static String cookieDomainName = "項目名"; //自己随便定義,跟上面一緻
@Autowired
private UserService userService;
private static Set excludeUrl=null;
{
excludeUrl=new HashSet();
excludeUrl.add("/personal");//攔截路徑中包含該詞的位址
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
HttpSession session=request.getSession(true);
User user=(User) session.getAttribute(WebKeys.USER_KEY);
String url=request.getRequestURI().toString();
//判斷使用者是否登入,一般是都沒登入的
if(user==null){
Cookie[] cookies = request.getCookies();//取cookie值,這裡還有其他網站的
if(cookies!=null){
String cookieValue = null;
//下面是找到本項目的cookie
for (int i = ; i < cookies.length; i++) {
if(cookieDomainName.equals(cookies[i].getName())){
cookieValue = cookies[i].getValue();
break;
}
}
//如果cookieValue為空 說明使用者上次沒有選擇“記住下次登入”執行其他
if(cookieValue==null){
if(url.contains("personal")){ response.sendRedirect(request.getContextPath()+"/loginInfo");
return false;
}
}else{
// 先得到的CookieValue進行Base64解碼
String cookieValueAfterDecode = new String(Base64.decode(cookieValue),"utf-8");
// 對解碼後的值進行分拆,得到一個數組,如果數組長度不為3,就是非法登陸
String cookieValues[] = cookieValueAfterDecode.split(":");
if(cookieValues.length!=){ response.sendRedirect(request.getContextPath()+"/loginInfo");
return false;
}
// 判斷是否在有效期内,過期就删除Cookie
long validTimeInCookie = new Long(cookieValues[]);
if (validTimeInCookie < System.currentTimeMillis()) {
// 删除Cookie
UserCookieUtil.clearCookie(response); response.sendRedirect(request.getContextPath()+"/loginInfo");
return false;
}
// 取出cookie中的使用者名,并到資料庫中檢查這個使用者名,
String username = cookieValues[];
User temp = userService.findByName(username);
// 如果user傳回不為空,就取出密碼,使用使用者名+密碼+有效時間+ webSiteKey進行MD5加密。與前面設定的進行比較,看是否是同一個使用者
if(temp!=null){
String md5ValueInCookie = cookieValues[];
String md5ValueFromUser = UserCookieUtil.getMD5(temp.getUserName() + ":" + temp.getPassWord() + ":" + validTimeInCookie + ":" + cookieDomainName);
// 将結果與Cookie中的MD5碼相比較,如果相同,寫入Session,自動登陸成功,并繼續使用者請求
if (md5ValueFromUser.equals(md5ValueInCookie)) {
session.setAttribute(WebKeys.USER_KEY, temp);
response.sendRedirect(request.getContextPath()+"/loginInfo");
return false;
}
}
}
}
}else{
if(url.contains("loginInfo")||url.contains("login")){
response.sendRedirect(request.getContextPath()+"/");
return false;
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
}
}
這樣完成了我們想要的功能。。。。