Cookie-網站登錄-下次自動登錄

做網站前端用戶登錄時需要有個下次自動登錄的功能。看了看各大網站都有這種功能。
問題描述:用戶登錄網站時,一般有個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 = 60 * 60 * 24 * 7 * 2;

// 保存Cookie到客戶端
// 傳遞進來的user對象中封裝了在登陸時填寫的用戶名與密碼
public static void saveCookie(User user, HttpServletResponse response) {
// cookie的有效期至(到哪一天)
long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000);
// 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(60 * 60 * 24 * 365 * 2);
// cookie有效路徑是網站根目錄
cookie.setPath("/");
// 向客戶端寫入
response.addCookie(cookie);
}

// 用戶註銷時,清除Cookie
public static void clearCookie(HttpServletResponse response) {
               //創建一個空cookie添加,覆蓋原來的達到清除目的
Cookie cookie = new Cookie(cookieDomainName, null);
cookie.setMaxAge(0);
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 * 2);
for (int i = 0; i < buffer.length; i++) {
sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
}
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 = 0; 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!=3){ response.sendRedirect(request.getContextPath()+"/loginInfo");
  return false;
  }
  // 判斷是否在有效期內,過期就刪除Cookie
  long validTimeInCookie = new Long(cookieValues[1]);
  if (validTimeInCookie < System.currentTimeMillis()) {
  // 刪除Cookie
  UserCookieUtil.clearCookie(response); response.sendRedirect(request.getContextPath()+"/loginInfo");
  return false;
  }
  // 取出cookie中的用戶名,併到數據庫中檢查這個用戶名,
  String username = cookieValues[0];
  User temp = userService.findByName(username);
  // 如果user返回不爲空,就取出密碼,使用用戶名+密碼+有效時間+ webSiteKey進行MD5加密。與前面設置的進行比較,看是否是同一個用戶
  if(temp!=null){
  String md5ValueInCookie = cookieValues[2];
  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);
}
}

這樣完成了我們想要的功能。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章