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);
}
}

这样完成了我们想要的功能。。。。

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