<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Dict.CN 在線詞典, 英語學(xué)習, 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統(tǒng)計

    留言簿(23)

    積分與排名

    優(yōu)秀學(xué)習網(wǎng)站

    友情連接

    閱讀排行榜

    評論排行榜

    安全的實現(xiàn)兩星期內(nèi)自動登陸功能(轉(zhuǎn))

     現(xiàn)在很多網(wǎng)站都有為用戶保存登陸信息(即保存Cookie)的功能,當用戶下一次進入網(wǎng)站時,可以幫助用戶自動登陸,使網(wǎng)站顯得更加友好。筆者通過研究ACEGI項目的自動登陸源碼,編寫了一個安全有效的實現(xiàn)兩星期自動登陸功能的JAVA工具類,在此要感謝傳智播客公司教學(xué)總監(jiān)張孝祥老師向筆者推薦了ACEGI項目。下面是具體的實現(xiàn)流程和實現(xiàn)代碼。

    先說一下流程:

    1.  保存用戶信息階段:

    當用戶登陸網(wǎng)站時,在登陸頁面填寫完用戶名和密碼后,如果用戶在提交時還選擇了“兩星期內(nèi)自動登陸”復(fù)選框,那么在后臺程序中驗證用戶名和密碼全都正確后,還要為用戶保存這些信息,以便用戶下一次可以直接進入網(wǎng)站;如果用戶沒有勾選“兩星期內(nèi)自動登陸”復(fù)選框,則不必為用戶保存信息,那么用戶在下一次登陸網(wǎng)站時仍需要填寫用戶名和密碼。

         在保存用戶信息階段,主要的工作是對用戶的信息進行加密并保存到客戶端。加密用戶的信息是較為繁瑣的,大致上可分 為以下幾個步聚:

    得到用戶名、經(jīng)MD5加密后的用戶密碼、cookie有效時間(本文設(shè)置的是兩星期,可根據(jù)自己需要修改)

    自定義的一個webKey,這個Key是我們?yōu)樽约旱木W(wǎng)站定義的一個字符串常量,這個可根據(jù)自己需要隨意設(shè)置

    將上兩步得到的四個值得新連接成一個新的字符串,再進行MD5加密,這樣就得到了一個MD5明文字符串

    將用戶名、cookie有效時間、MD5明文字符串使用“:”間隔連接起來,再對這個連接后的新字符串進行Base64編碼

    設(shè)置一個cookieName,cookieName和上一步產(chǎn)生的Base64編碼寫入到客戶端。

                 

    2.  讀取用戶信息:

    其實弄明白了保存原理,讀取及校驗原理就很容易做了。讀取和檢驗可以分為下面幾個步驟:

    根據(jù)設(shè)置的cookieName,得到cookieValue,如果值為空,就不幫用戶進行自動登陸;否則執(zhí)行讀取方法

    cookieValue進行Base64解碼,將取得的字符串以split(“:”)進行拆分,得到一個String數(shù)組cookieValues(此操作與保存階段的第4步正好相反),這一步將得到三個值:

           cookieValues[0] ---- 用戶名

           cookieValues[1] ---- cookie有效時間

           cookieValues[2] ---- MD5明文字符串

    判斷cookieValues的長度是否為3,如果不為3則進行錯誤處理。

    如果長度等于3,取出第二個,cookieValues[1],此時將會得到有效時間(long型),將有效時間與服務(wù)器系統(tǒng)當前時間比較,如果小于當前時間,則說明cookie過期,進行錯誤處理。

    如果cookie沒有過期,就取cookieValues[0],這樣就可以得到用戶名了,然后去數(shù)據(jù)庫按用戶名查找用戶。

    如果上一步返回為空,進行錯誤處理。如果不為空,那么將會得到一個已經(jīng)封裝好用戶信息的User實例對象user

    取出實例對象user的用戶名、密碼、cookie有效時間(即cookieValues[1])、webKey,然后將四個值連接起來,然后進行MD5加密,這樣做也會得到一個MD5明文字符串(此操作與保存階段的第3步類似)

    將上一步得到MD5明文與cookieValues[2]進行equals比較,如果是false,進行錯誤處理;如果是true,則將user對象添加到session中,幫助用戶完成自動登陸

    完整的代碼,用途請參見注釋

    CookieUtil.java

    處理cookie的工具類,包括讀取,保存,清除三個主要方法。

    package cn.itcast.util;


    import java.io.IOException;

    import java.io.PrintWriter;

    import java.io.UnsupportedEncodingException;


    import javax.servlet.FilterChain;

    import javax.servlet.ServletException;

    import javax.servlet.http.Cookie;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.servlet.http.HttpSession;

    import java.security.MessageDigest;

    import java.security.NoSuchAlgorithmException;


    import cn.itcast.bean.User;

    import cn.itcast.dao.UserDAO;

    import cn.itcast.factory.DaoImplFactory;

    import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;


    /*

     * 2007.09.21 by lyhapple

     * 
    */



    public class CookieUtil {

           
    //保存cookie時的cookieName

           
    private final static String cookieDomainName = “cn.itcast”;

           

           
    //加密cookie時的網(wǎng)站自定碼

           
    private final static String webKey = “itcast”;

           

    //設(shè)置cookie有效期是兩個星期,根據(jù)需要自定義

           
    private final static long cookieMaxAge = 60 * 60 * 24 * 7 * 2;

           

           
    //保存Cookie到客戶端--------------------------------------------------------------------------------------------------------

           
    //在CheckLogonServlet.java中被調(diào)用

           
    //傳遞進來的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 
    = new Cookie(cookieDomainName, cookieValueBase64);

                  
    //存兩年(這個值應(yīng)該大于或等于validTime)

    cookie.setMaxAge(
    60 * 60 * 24 * 365 * 2); 

    //cookie有效路徑是網(wǎng)站根目錄

                  cookie.setPath(
    "/");

                  
    //向客戶端寫入

                  response.addCookie(cookie);

           }


           

           
    //讀取Cookie,自動完成登陸操作--------------------------------------------------------------------------------------------

           
    //在Filter程序中調(diào)用該方法,見AutoLogonFilter.java

           
    public static void readCookieAndLogon(HttpServletRequest request, HttpServletResponse response, 

    FilterChain chain) 
    throws IOException, ServletException,UnsupportedEncodingException{

                         

    //根據(jù)cookieName取cookieValue

    Cookie cookies[] 
    = request.getCookies();

                         String cookieValue 
    = null;

                         
    if(cookies!=null){

                                
    for(int i=0;i<cookies.length;i++){

                                       
    if (cookieDomainName.equals(cookies[i].getName())) {

                                              cookieValue 
    = cookies[i].getValue();

                                              
    break;

                                       }


                                }


                         }



                         
    //如果cookieValue為空,返回,

                         
    if(cookieValue==null){

                                
    return;

                         }


                  

                  
    //如果cookieValue不為空,才執(zhí)行下面的代碼

                  
    //先得到的CookieValue進行Base64解碼

                  String cookieValueAfterDecode 
    = new String (Base64.decode(cookieValue),"utf-8"); 

                  

                  
    //對解碼后的值進行分拆,得到一個數(shù)組,如果數(shù)組長度不為3,就是非法登陸

                  String cookieValues[] 
    = cookieValueAfterDecode.split(":");

                  
    if(cookieValues.length!=3){

                         response.setContentType(
    "text/html;charset=utf-8");

                         PrintWriter out 
    = response.getWriter();

                         out.println(
    "你正在用非正常方式進入本站");

                         out.close();

                         
    return;

                  }


                  

                  
    //判斷是否在有效期內(nèi),過期就刪除Cookie

                  
    long validTimeInCookie = new Long(cookieValues[1]);

                  
    if(validTimeInCookie < System.currentTimeMillis()){

                         
    //刪除Cookie

                         clearCookie(response);

                         response.setContentType(
    "text/html;charset=utf-8");

                         PrintWriter out 
    = response.getWriter();

                         out.println(
    "<a href=’logon.jsp’>你的Cookie已經(jīng)失效,請重新登陸</a>");

                         out.close();

                         
    return;

                  }


                  

                  
    //取出cookie中的用戶名,并到數(shù)據(jù)庫中檢查這個用戶名,

                  String username 
    = cookieValues[0];

                  

                  
    //根據(jù)用戶名到數(shù)據(jù)庫中檢查用戶是否存在

                  UserDAO ud 
    = DaoImplFactory.getInstance();

                  User user 
    = ud.selectUserByUsername(username);

                  

                  
    //如果user返回不為空,就取出密碼,使用用戶名+密碼+有效時間+ webSiteKey進行MD5加密

                  
    if(user!=null){

                         String md5ValueInCookie 
    = cookieValues[2];

                         String md5ValueFromUser 
    =getMD5(user.getUserName() + ":" + user.getPassword()

                                       
    + ":" + validTimeInCookie + ":" + webKey);

                         
    //將結(jié)果與Cookie中的MD 5碼 相比較,如果相同,寫入Session,自動登陸成功,并繼續(xù)用戶請求

                         
    if(md5ValueFromUser.equals(md5ValueInCookie)){

                                HttpSession session 
    = request.getSession(true);

                                session.setAttribute(
    "user", user);

                                chain.doFilter(request, response);

                         }


                  }
    else{

           
    //返回為空執(zhí)行

                         response.setContentType(
    "text/html;charset=utf-8");

                         PrintWriter out 
    = response.getWriter();

                         out.println(
    "cookie驗證錯誤!");

                         out.close();

           
    return;

    }


           }


           

           
    //用戶注銷時,清除Cookie,在需要時可隨時調(diào)用------------------------------------------------------------

           
    public static void clearCookie( HttpServletResponse response){

                  Cookie cookie 
    = new Cookie(cookieDomainName, null);

                  cookie.setMaxAge(
    0);

                  cookie.setPath(
    "/");

                  response.addCookie(cookie);

           }



    //獲取Cookie組合字符串的MD 5碼 的字符串----------------------------------------------------------------------------

                  
    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){

                                e1.printStackTrace();

    }


                         
    return result;

                  }


           

    //將傳遞進來的字節(jié)數(shù)組轉(zhuǎn)換成十六進制的字符串形式并返回

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

                                sb.append(Character.forDigit(buffer[i] 
    & 0x 0f , 16));

                         }


                         
    return sb.toString();

                  }


    }

    下面的是對CookieUtil工具類各方法的調(diào)用演示:

    User.java

    封裝用戶信息的JavaBean對象模型

    package com.itcast.bean;


    public class User {

           
    private int id;

           

           
    private String userName;


           
    private String password;

           

           
    public String getPassword() {

                  
    return password;

           }



           
    public void setPassword(String password) {

                  
    this.password = password;

           }



           
    public String getUserName() {

                  
    return userName;

           }



           
    public void setUserName(String userName) {

                  
    this.userName = userName;

           }



           
    public int getId() {

                  
    return id;

           }



           
    public void setId(int id) {

                  
    this.id = id;

           }


    }


    AutoLogonFilter.java

    過濾器程序,可在WEB-INF/web.xml中設(shè)置過濾規(guī)則,本文對過濾規(guī)則不作介紹,此程序主要作用是檢查用戶在上一次登陸時是否保存了Cookie,如果保存了,就處理Cookie信息,并幫助用戶自動登陸

    本程序主要調(diào)用了CookieUtil.java中的讀取與自動登陸方法,即readCookieAndLogon方法

    package cn.itcast.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 javax.servlet.http.HttpSession;


    import cn.itcast bean.User;

    import cn.itcast.util.CookieUtil;


    public class AutoLogonFilter implements Filter {

           

           
    public void destroy() {

           }


           

    //保存cookie時的cookieName,與CookieUtil.java中的設(shè)置相同 

           
    private final static String cookieDomainName = “cn.itcast”;

           

           
    public void doFilter(ServletRequest req, ServletResponse resp,

                         FilterChain chain) 
    throws IOException, ServletException {

                  HttpServletRequest request 
    = (HttpServletRequest)req;

                  HttpServletResponse response 
    = (HttpServletResponse)resp;

                  HttpSession session 
    = request.getSession(true);

                  User user 
    = (User)session.getAttribute("user");

                  

                  
    //如果封裝的user不為空,說明已經(jīng)登陸,則繼續(xù)執(zhí)行用戶的請求.下面的就不處理了

                  
    if(user!=null){

                         chain.doFilter(request,response);

                         
    return;

                  }


                  

                  
    //user為空,說明用戶還沒有登陸,就嘗試得到瀏覽器傳送過來的Cookie

                  Cookie cookies[] 
    = request.getCookies();

                  String cookieValue 
    = null;

                  
    if(cookies!=null){

                         
    for(int i=0;i<cookies.length;i++){

                                
    if (cookieDomainName.equals(cookies[i].getName())) {

                                       cookieValue 
    = cookies[i].getValue();

                                       
    break;

                                }


                         }


                  }



                  
    //如果cookieValue為空,也繼續(xù)執(zhí)行用戶請求

                  
    if(cookieValue==null){

                         chain.doFilter(request,response);

                         
    return;

                  }



                  
    //cookieValue不為空執(zhí)行下面的方法,調(diào)用CookieUtil.java中的readCookieAndLogon方法 

                  
    try{

                         CookieUtil.readCookieAndLogon(cookieValue, request, response, chain);

                  }
    catch(Exception e){

                         e.printStackTrace();

                  }


           }



           
    public void init(FilterConfig arg0) throws ServletException {

           }


    }


    CheckLogonServlet.java

    驗證用戶登陸信息的Servlet,此程序調(diào)用了CookieUtil.java中的saveCookie方法

    package cn.itcast.servlet;


    /*

     * update 2007.09.23 by lyhapple

     * 檢查用戶登陸

     * 
    */



    import java.io.IOException;


    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.servlet.http.HttpSession;


    import cn.itcast.bean.User;

    import cn.itcast.dao.UserDAO;

    import cn.itcast.factory.DaoImplFactory;

    import cn.itcast.util.CookieUtil;


    public class CheckLogonServlet extends HttpServlet {


           
    public void doGet(HttpServletRequest request, HttpServletResponse response)

                         
    throws ServletException, IOException {

                  doPost(request, response);

           }



           
    public void doPost(HttpServletRequest request, HttpServletResponse response)

                         
    throws ServletException, IOException {

                  request.setCharacterEncoding(
    "utf-8");

                  String username 
    = request.getParameter("username").trim();

                  String password 
    = CookieUtil.getMD5(request.getParameter("password"));

                  String remeberMe 
    = request.getParameter("remeberMe");

                  HttpSession session 
    = request.getSession(false);


                  
    // 將接收到的用戶名傳遞到UserDao的checkUser方法中,檢查用戶

                  
    // 返回一個User類型的對象

                  UserDAO ud 
    = DaoImplFactory.getInstance();

                  User user 
    = ud.selectUserByUsername(username);

                  
    if (user == null{

                         request.setAttribute(
    "checkUserError","<a href='register.jsp'><font color=red>用戶名不存在,請先注冊</font></a>");

                         request.getRequestDispatcher(
    "index.jsp").forward(request, response);

                         
    return;

                  }



                  
    if(!password.equals(user.getPassword())){

                         request.setAttribute(
    "checkPasswordError","<font color=red>密碼輸入錯誤,請重新輸入</font>");

                         request.getRequestDispatcher(
    "index.jsp").forward(request, response);

                         
    return;

                  }


                  

                  
    //保存Cookie,這里調(diào)用了CookieUtil.java中的saveCookie方法,將上面的user對象作為參數(shù)傳遞 

                  
    if ("on".equals(remeberMe)) {

                         CookieUtil.saveCookie(user, response);

                  }


                  
    //在Session中保存用戶信息,并轉(zhuǎn)向用戶的個人信息頁面

                  session.setAttribute(
    "user", user);

                  request.getRequestDispatcher(
    "User/userInfo.jsp").forward(request,response);

           }


    }

    UserDAO.javaDaoImplFactory.java屬于持久層相關(guān)的程序,這里就不貼出來了,讀者可根據(jù)自己需要選擇不同的持久層框架,在本程序中只要實現(xiàn)查詢用戶的功能就可以了

    posted on 2007-10-11 12:39 都市淘沙者 閱讀(445) 評論(0)  編輯  收藏 所屬分類: Java Basic/Lucene/開源資料

    主站蜘蛛池模板: 人妻在线日韩免费视频| 日韩激情淫片免费看| 亚洲另类少妇17p| 亚洲Av高清一区二区三区| 香蕉免费在线视频| 大香人蕉免费视频75| 亚洲av色福利天堂| 黄页网站在线视频免费| 在线观看免费人成视频色9| 亚洲AV综合色区无码一区| 无码日韩人妻AV一区免费l| 99精品全国免费观看视频| 亚洲va中文字幕无码久久不卡| 午夜亚洲国产精品福利| 性生交片免费无码看人| 亚洲国产综合专区在线电影| 深夜免费在线视频| 国产成人精品免费直播| 久久亚洲国产成人影院| 在线人成精品免费视频| 亚洲国产精品成人精品无码区 | 免费二级毛片免费完整视频| 亚洲国产成人久久精品app| 日韩免费电影网址| 亚洲一区二区三区偷拍女厕| 毛片亚洲AV无码精品国产午夜| 免费无码肉片在线观看| 亚洲精品无码久久毛片波多野吉衣 | 亚洲av永久无码精品天堂久久| 四虎影视在线影院在线观看免费视频| 国产亚洲人成A在线V网站| 色妞www精品视频免费看| 日本久久久免费高清| 亚洲日产乱码一二三区别| 日本精品人妻无码免费大全| 亚洲黄色网站视频| 亚洲精品在线免费观看视频| 色婷婷六月亚洲婷婷丁香| 久久精品国产这里是免费| 亚洲av永久无码精品漫画| 男人进去女人爽免费视频国产|