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

做網站前端用戶登錄時需要有個下次自動登錄的功能。看了看各大網站都有這種功能。
問題描述:用戶登錄網站時,一般有個checkbox讓用戶選擇是否可以下次自動登錄。選擇後,即使用戶關閉瀏覽器,下次再訪問這個網站時直接就登錄了,不需要用戶名和密碼。

主要使用cookie。cookie是web服務器存放在客戶端的一個文件,主要用來記錄用戶瀏覽網站信息的。它主要有兩個功能:一個是記錄用戶信息,下次自動登錄的。另一個是記錄跟蹤統計用戶瀏覽網頁的習慣(瀏覽過哪些網站?停留時間,利用這個可以做訪問量統計),我們主要用到第一個功能。配合代碼講解:

核心類:CookieUtil

package com.nt.italk.framework.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import com.nt.italk.member.domain.bo.CookieUser;

public class CookieUtil {
    public static final String cookieDomainName = "mem_cookie_info";

    public static final String webKey = "italk";
    // 設置cookie有效期是2個星期
    public static final long cookieMaxAge = 3600 * 24 * 14;

    public static void saveCookie(CookieUser user, HttpServletResponse response) {
        long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000);
        String pwdMd5 = DigestUtils.md5Hex(user.getPassWord());
        if (pwdMd5.length() > 20) {
            pwdMd5 = pwdMd5.substring(0, 20);
        }
        String cookieValueWithMd5 = getMD5(user.getUserEmail() + "_" + pwdMd5
                + "_" + validTime + "_" + webKey);
        String cookieValue = user.getUserEmail() + "_" + validTime + "_"
                + cookieValueWithMd5;
        String cookieValueBase64 = new String(Base64.encodeBase64(cookieValue
                .getBytes()));
        Cookie cookie = new Cookie(cookieDomainName, cookieValueBase64);
        // 這個值應該大於或等於validTime
        cookie.setMaxAge(3600 * 24 * 28);

        cookie.setPath("/");
        response.addCookie(cookie);
    }

    public static void clearCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie(cookieDomainName, null);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    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值。等用戶選中下次自動登錄並且本次登錄成功後調用一下上面類的保存方法。

下次當用戶在訪問該網站時可以用攔截器CookieInteceptor(我用的是攔截器)攔截路徑判斷一下cookie是否存有該網站的user對象:有就自動登錄。

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.nt.italk.framework.session.SessionUtil;
import com.nt.italk.framework.util.CookieUtil;
import com.nt.italk.member.domain.bo.BMember;
import com.nt.italk.member.domain.vo.VMemberSession;
import com.nt.italk.member.service.MemberService;

public class CookieInteceptor implements HandlerInterceptor
{
    // 無需安全認證的url
    private List<String> excludeUrl = new ArrayList<String>();
    @Autowired
    private MemberService memberService;

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception
    {
        String url = request.getRequestURI().replaceFirst(request.getContextPath(), "");

        for (int i = 0, len = this.excludeUrl.size(); i < len; i++)
        {
            if (url.matches(this.excludeUrl.get(i)))
            {
                return true;
            }
        }
        Object memberInfo = SessionUtil.getMemberSession(request);
        //判斷用戶是否登陸
        if (memberInfo==null)
        {
            Cookie[] cookies=request.getCookies();
            if (cookies!=null && cookies.length>0)
            {
                String cookieValue = null;
                for (int i = 0; i < cookies.length; i++)
                {
                    if (CookieUtil.cookieDomainName.equals(cookies[i].getName()))
                    {
                        cookieValue=cookies[i].getValue();
                        break;      
                    }
                }
                if (null != cookieValue)
                {
                    //解碼
                    String cookieValueAfterDecode = new String(Base64.decodeBase64(cookieValue.getBytes()), "utf-8");
                    String[] cookieValues = cookieValueAfterDecode.split("_");
                    if (cookieValues.length==3)
                    {
                        //有效期判斷
                        long validTimeInCookie = new Long(cookieValues[1]);
                        if (validTimeInCookie < System.currentTimeMillis())
                        {
                            //刪除cookie
                            CookieUtil.clearCookie(response);
                        }else {
                            //取出會員email
                            String email = cookieValues[0];
                            BMember bMember = memberService.createLocalCookieLogin(email);

                            if (bMember!=null)
                            {

                                String md5ValueInCookie = cookieValues[2];
                                String md5ValueFromMember = CookieUtil.getMD5(bMember.getEmail() + "_" + bMember.getPassWord() + "_" + validTimeInCookie + "_" + CookieUtil.webKey);
                                if (md5ValueFromMember.equals(md5ValueInCookie))
                                {
                                    // set member session info
                                    VMemberSession vMemberSession = new VMemberSession();
                                    vMemberSession.setId(bMember.getId());
                                    vMemberSession.setNickname(bMember.getNickname());
                                    vMemberSession.setAvatar(bMember.getAvatar());
                                    vMemberSession.setEmail(bMember.getEmail());
                                    vMemberSession.setNatLangId(bMember.getNatLangId());
                                    vMemberSession.setSex(bMember.getSex());
                                    vMemberSession.setCountryId(bMember.getCountryId());
                                    vMemberSession.setNowCountryId(bMember.getNowCountryId());
                                    vMemberSession.setBirthday(bMember.getBirthday());
                                    vMemberSession.setLangex(bMember.getLangex());
                                    vMemberSession.setComleam(bMember.getComleam());
                                    SessionUtil.setMemberSession(request, vMemberSession);
                                }
                            }
                        }
                    }
                }
            }
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception
    {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception
    {
        // TODO Auto-generated method stub

    }

    public List<String> getExcludeUrl()
    {
        return excludeUrl;
    }

    public void setExcludeUrl(List<String> excludeUrl)
    {
        this.excludeUrl = excludeUrl;
    }

}

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

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