2012-10-29 68 views
6

我試圖實現登錄(記住我)應用程序,並且我遇到了一個問題來管理cookie。當我做註冊(新成員)或登錄(即已經被註冊的成員),我做的服務器:登錄,記住我,使用java servlet和jsp的應用程序

Cookie returnVisitorCookie = new Cookie("repeatVisitor", "yes"); 
returnVisitorCookie.setMaxAge(60*60*24*365); // 1 year 
response.addCookie(returnVisitorCookie); 

在響應我是從瀏覽器中獲取。例如:visitor.login(response)。

當我做SIGNOUT時,我刪除了cookie。但似乎我有更多的餅乾 ,它應該是,我的意思是如果我註冊了2個成員並註銷,我仍然有名稱=「repeatVisitor」和值=「是」的Cookie。

也許是因爲我把cookie放在不同的響應中。

任何人都可以給我一個idae我做錯了什麼,我應該如何實現呢? 謝謝

+1

如果您正在設置此cookie,如何在不註銷的情況下注冊兩個用戶?這聽起來像是你在設置它之前多次設置它,這是不可能的 - 這意味着當你已經登錄時你已經登錄。 –

+2

@Phhite即使您在登錄時登錄,上面的代碼也會覆蓋現有的cookie。 – doublesharp

+0

我不熟悉Java如何處理cookie,這就是爲什麼我沒有發佈答案。我知道在其他後端語言中也是如此。 –

回答

0

您將在後續請求中保留至少一年的repeatVisitor cookie,您已經指示客戶端的瀏覽器做到這一點,「讓cookie保持一年」。從隨後的請求頭中刪除cookie不會阻止瀏覽器重新添加它。

要實現記得我成功,你需要

  1. 使用安全令牌,不只是一個標誌,上面寫着「重複用戶:是的」。生成使用類似java's UUID class唯一標識一個遊客安全的唯一原因,所以有人只是不攔截請求,並把東西在標題爲你處理

  2. 積極管理你每產生的安全令牌用戶。這意味着您將生成的令牌存儲在某個持久性存儲中,並檢查針對此存儲的重複請求。在這個商店裏,你將管理令牌過期等等。因此,在你的持久化存儲,可以標記標記爲非活動您或過期

作爲替代,越容易記得我的路線是設置你記住,我爲這樣你們就設定一個固定的時間段HttpServletRequest對象中的cookie過期日期。也就是說,您的複選框將顯示remember me for 2 weeks,然後將您的Cookie過期設置爲2周。隨後的相同cookie標記的陳述將自動管理而不會受到壓力。

1

我有時會發現最好的學習或理解方式就是看一個例子。下面是一些代碼,我們使用了一個工作網站:

@WebServlet(name = "Login", urlPatterns = {"/authorization/Login"}) 
public class Login extends HttpServlet { 

    /** 
    * Processes requests for both HTTP 
    * <code>GET</code> and 
    * <code>POST</code> methods. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 

     PrintWriter out = response.getWriter(); 
     try { 
      System.out.println("Reached login"); 
      if (!Authorization.isLoggedIn(request)) { 
       String login = request.getParameter("login"); 
       String password = request.getParameter("password"); 
       boolean remember = Boolean.parseBoolean(request.getParameter("remember")); 

       System.out.println("Reached login "+login+", "+password+","+remember); 
       if (!Authorization.validateLogin(login, password)) { 
        Logger.getLogger(Login.class.getName()).log(Level.INFO, 
          "Failed login (invalid password) from {0} for {1}", 
          new String[]{request.getRemoteAddr(), login}); 
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid username or password!"); 
        return; 
       } 
       //So far so good... Get the user object from the database (unique login names) 
       DB_User user = DB_User.get(login); 
       if (!user.getActive()) { 
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Your account is no longer active!"); 
        return; 
       } 
       String sessionID = Authorization.createNewSession(user, request.getRemoteAddr(), remember); 
       Cookie sessionCookie = new Cookie("my_application.session_id", sessionID); 
       sessionCookie.setDomain(request.getServerName()); 
       sessionCookie.setPath(request.getContextPath()); 
       if (remember) { 
        sessionCookie.setMaxAge(ServerConfig.getLoginSessionTimeout()); 
       } 

       response.addCookie(sessionCookie); 
      } 
      response.sendRedirect("/app/myAccount.jsp"); 
     } catch (Throwable ex) { 
      Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex); 
      ServletUtils.handleException(ex, response); 
     } finally { 
      out.flush(); 
      out.close(); 
     } 
    } 

    // +HttpSerlet default methods here. (doGet, doPost, getServletInfo) 
} 

註銷的servlet例如:

@WebServlet(name = "Logout", urlPatterns = {"/authorization/Logout"}) 
public class Logout extends HttpServlet { 

    /** 
    * Processes requests for both HTTP 
    * <code>GET</code> and 
    * <code>POST</code> methods. 
    * 
    * @param request servlet request 
    * @param response servlet response 
    * @throws ServletException if a servlet-specific error occurs 
    * @throws IOException if an I/O error occurs 
    */ 
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     response.setContentType("text/html;charset=UTF-8"); 
     PrintWriter out = response.getWriter(); 
     try { 
      String sessionID = ServletUtils.getCookieValue(request.getCookies(),"my_application.session_id"); 

      if (sessionID != null) { 
       SQLManager sql = ServerConfig.getSql(); 
       sql.deleteFromTable("login_session", "session_id = " + SQLString.toSql(sessionID)); 

       Cookie sessionCookie = new Cookie("my_application.session_id", null); 
       sessionCookie.setDomain(ServletUtils.getCookieDomain(request)); 
       sessionCookie.setPath("/you_app_name"); 
       sessionCookie.setMaxAge(0); 
       response.addCookie(sessionCookie); 
      } 
      response.sendRedirect("/security/login.jsp"); 

     } catch (Throwable ex) { 
      Logger.getLogger(Logout.class.getName()).log(Level.SEVERE, null, ex); 
      ServletUtils.handleException(ex, response); 
     } finally { 
      out.close(); 
     } 
    } 
} 

有我們做,你會發現一些輔助類,但這個概念仍然存在。希望這會有所幫助