1. 程式人生 > >Session和Cookie的聯絡與區別

Session和Cookie的聯絡與區別

這裡有一篇資料:https://pan.baidu.com/s/1tjUyL7DwY2ganIfKnz_AJQ

在講session和coookie之前,要先知道會話跟蹤的概念。

在常見的Java Web開發中,我們經常會使用會話跟蹤技術,來記錄某一時段使用者的行為。由於Web訪問中使用的HTTP協議是無狀態的——也就是說,當客戶端的請求到來,服務端做出響應後,連線就關閉了。這樣的好處是不用維護連線,節省資源;但缺點就是難於跟蹤客戶端的狀態、不能唯一地標識使用者,記錄使用者的狀態。

例如,我們一般的網路Web請求需要針對使用者做一些控制,如登入、使用者管理等操作。可以用會話和狀態解決這種需求。

會話&狀態

  • 會話:當前瀏覽器與伺服器間多次的請求、響應關係,被稱作一個會話。獲取使用者標識或授權資訊。
  • 狀態:記憶請求和處理的資訊

在一個請求的過程中,響應的時候,由伺服器給我分配一個唯一ID號,這樣就能區別不同的使用者了;需要再次請求時,伺服器就能通過這個ID來進行使用者判斷。一般使用session和cookie聯動完成這種需求。另外還有一種SSL會話機制、URL重寫技術。

Cookies

最常用的回覆跟蹤技術。由伺服器傳送給客戶的片段資訊,儲存在客戶端瀏覽器的記憶體或硬碟上,在客戶隨後對該伺服器的請求中發回。

Cookies以鍵值對的方式記錄會話的跟蹤內容,伺服器利用響應報頭Set-Cookie來發送Cookie資訊。傳送這些報頭中具有不同的規範,可理解為不同的設定方式,包括了name/comment等格式。

一個例子如下:1545204942712

瀏覽器在接受cookie後,下次傳送給同一伺服器的請求,也會發送請求報頭:Cookie: uid=zhangsan. 伺服器取得不同的請求報頭,就能實現不同使用者的會話跟蹤。

URL重寫

Cookie對使用者透明,且一般永續性高,是在請求報頭中被傳送的,不會和傳送的內容混淆。這樣,由於Cookie可以儲存在本地的磁碟中,可能會造成一些隱私和安全問題,使用者可以使用瀏覽器禁用Cookie。

當Cookie被禁用後,服務端可以使用URL重寫機制跟蹤使用者會話。URL重寫時在URL中嵌入標識客戶的SessionID,Servlet容器可以解析URL的方式獲取SessionID,與特定的會話關聯起來。

在Servlet規範中,這個引數的名字必須是jsessionid,一個示例:http://www.a.org/index.jsp;jsessionid=1234&name=aa。所有的URL需要進行URL編碼,來防止安全問題。

Session

伺服器為每一個會話建立一個session物件,分配一片記憶體空間,使用一個唯一的SessionID進行標識。請求過程中,使用者的資料儲存在相應的HttpSession物件內。在後續的請求中,使用者可以根據會話的ID來獲取到儲存在session中的資料。

具體的過程:在Servlet容器中,HttpSession物件會被分配一個唯一的SessionID,將其作為Cookie(或者URL的一部分,URL重寫機制)傳送給瀏覽器,瀏覽器在記憶體中儲存這個Cookie。當客戶端再次傳送HTTP請求時,瀏覽器將Cookie隨請求一起傳送,Servlet容器從中獲取SessionID,找到對應的HttpSession物件,得到客戶資訊。

生命週期:

  • 會話開始時建立,當瀏覽器訪問伺服器時,伺服器為每個瀏覽器建立不同的session物件;開闢記憶體空間,儲存資料資訊。
  • 呼叫session. invalidate()方法,使session物件失效;訪問時間間隔大於非活動時間間隔, session物件失效;關閉瀏覽器時,session物件失效。清空當前的記憶體的瀏覽器相關資料。注:同一瀏覽器的不同視窗可能是同一個程序,所以關閉後不會失效;要注意開啟多個瀏覽器的方式。
public void doGet(HttpServletRequest request, HttpServletResponse  
                             response)  throws ServletException, IOException {	HttpSession session = request.getSession(true); 
	Object count = session.getAttribute("COUNTER");
	int counter = 0;
	if (count == null) {
	       counter = 1;
	       //將第一次計數存入session
	       session.setAttribute("COUNTER", new Integer(1));
               } else {
                     counter = ((Integer) count).intValue();
                     counter++;//計數加一
//將計數存入session
session.setAttribute("COUNTER", new Integer(counter));
               }
}

示例:在登入頁面使用者已錄入使用者名稱,編寫一個Servlet接收該資料,並把使用者名稱值儲存在HttpSession物件內

public void doGet(HttpServletRequest request, HttpServletResponse 
                             response)   throws ServletException, IOException {

	String userName=request.getParameter("userName");
	HttpSession session=request.getSession();
	if (userName!=null && "".equals(userName))
		session.setAttribute("userName", userName);
	else
		response.sendRedirect("index.html");
}
...

Cookie與Session的區別

  • Cookie在客戶端儲存資訊,由伺服器建立傳送給客戶的片段資訊。
  • Session在伺服器端儲存資訊,可以採用Cookie或URL重寫的方式儲存SessionID
    String user = request.getParameter("user");
    String pass = request.getParameter("pass");
    Cookie userCookie = new Cookie("user", user);
    userCookie.setMaxAge(60 * 60 * 24 * 365);//設定Cookie的最大有效期,秒為單位
    Cookie passCookie = new Cookie("pass", pass);
    passCookie.setMaxAge(60 * 60 * 24 * 365);
    response.addCookie(userCookie);
    response.addCookie(passCookie);

重點:

  • Session和Cookie的最大區別是,Session在服務端儲存資訊,Cookie在客戶端儲存資訊。為了跟蹤使用者會話,伺服器在建立Session後,需要將SessionID交給客戶端,在客戶端下次請求時,將這個ID隨請求一同發回。將SessionID傳送給客戶端的方式可以使用cookie或者URL重寫的方式。
  • 一般而言,將直接用來跟蹤使用者會話的Cookie成為會話Cookie,在Servlet規範中,會話Cookie的名字必須是JsessionID,它通常也儲存在記憶體中。在瀏覽器記憶體中的會話Cookie不能被不同瀏覽器程序共享。(可能讀者開啟多個瀏覽器,也能看到同樣的結果,那是因為這些瀏覽器視窗是同一個程序中的多個執行緒;讀者可以使用程序檢視器檢視)
  • 對於儲存在硬碟上的Cookie,多個瀏覽器時程序間是可以共享的。Session不會隨著瀏覽器的關閉而消失,只是因為記憶體中Cookie不在,重新開啟的瀏覽器會開啟一個新的會話。原Session一般會直到超時時間才會被伺服器銷燬。
  • Session由於儲存在服務端,若儲存大量將會造車伺服器的效能負載問題。