cookie、session總結

木瓜芒果發表於2018-07-04

  前幾天在除錯第三方支付介面時碰到一個session失效問題,用了幾天時間才搞明白,現在回想一下,主要還是由於cookie和session這一塊的一些基本概念沒有搞清楚,現總結一下。

  瀏覽器使用HTTP協議作為應用層協議,而HTTP協議是一個無狀態協議,但是通常web站點希望能夠識別使用者,可能是因為伺服器希望限制使用者的訪問,或者因為它希望把內容與使用者身份聯絡起來。這就需要將瀏覽器與web伺服器之間多次互動當作一個整體來處理,並且將多次互動所涉及的資料及狀態儲存下來,通常有兩種方案:cookie和session。

cookie

  伺服器為了識別使用者身份而臨時存放在瀏覽器端的少量資料。瀏覽器器訪問伺服器時,伺服器將一些資料以Cookie訊息頭的形式傳送給瀏覽器(由程式指定),瀏覽器會將這些資料儲存下來;當瀏覽器再次訪問伺服器時,會將這些資料以Cookie訊息頭的方式傳送給伺服器。

使用Cookie

//新增Cookie
Cookie c = new Cookie(String name,String value);
response.addCookie(c);
//讀取Cookie
Cookie[] request.getCookies();
String cookie.gtName()
String cookie.getValue()

Cookie編碼問題

  cookie只能存放合法的ascii字元,如果要存放中文,可以將中文轉換成合法的asscii字元形式,通過如下方式進行編解碼,編碼後的字串可以存到cookie中,讀取時再進行解碼。

String URLEncoder.encode(String str,String charset); //編碼
String URLDecoder.decode(String str,String charset); //解碼

Cookie生存時間問題

可以通過cookie.setMaxAge(int seconds)來設定:
seconds>0,瀏覽器會將cookie儲存在硬碟上,超過指定時間cookie失效;
seconds<0,預設值,瀏覽器會將cookie存在記憶體中,關閉瀏覽器後cookie失效;
seconds=0,刪除cookie;

Cookie的路徑問題  

  瀏覽器端儲存的cookie內容主要包括:名字,值,過期時間,路徑和域名。

  瀏覽器在訪問伺服器上的某個地址時,會比較Cookie的路徑與該路徑是否匹配,瀏覽器只會將路徑匹配的Cookie傳送給伺服器。cookie的預設路徑為新增該cookie的web元件的路徑,比如/servlet/addCookie.jsp新增了一個cookie,則瀏覽器端儲存該cookie對應的預設路徑為:/servlet。

  在瀏覽器端一般會儲存多個cookie,當瀏覽器要訪問伺服器時如何決定要將哪個cookie新增至訊息頭中呢?

匹配規則如下:
  要訪問的地址必須是cookie的路徑或其子路徑,而且域名需一致。
  比如瀏覽器端儲存的cookie的路徑是/servlet/work/,當訪問/servlet/buy.jsp這個頁面時是不會將該cookie放入訊息頭中的,而當訪問/servlet/work/buy.jsp或/servlet/work/flow/buy.jsp兩者之一時,瀏覽器是會將前面的cookie放入訊息頭之中的。

cookie的限制

a.cookie不安全

b.cookie可以被使用者禁止

c.cookie只能儲存少量資料,4k左右

d.瀏覽器儲存的cookie的數量也有限制(大約幾百個)

e.cookie只能儲存字串

session(會話)

  伺服器端為了儲存狀態而建立的一個特殊的物件。

  瀏覽器訪問伺服器時,伺服器會建立一個特殊物件session(由程式指定,該物件有一個唯一的id,本文稱之為sessionId),伺服器會將sessionId以cookie形式傳送給瀏覽器;當瀏覽器再次訪問伺服器時,會在訊息頭中帶有包含sessionId的cookie訊息頭,伺服器端可以利用這個sessionId找到相應的物件,來儲存一些狀態值。

使用session

//方式一
HttpSession session = request.getSession(boolean flag); //當flag為true時,先檢視請求當中有沒有sessionId,如果有,則依據該sessionId查詢對應的session物件,找到則返回,找不到則建立新session物件;如果請求當中沒有,則直接創捷session物件;
//當flag為false,與true類似,只是在沒有找到session物件時返回空

//方式二
HttpSession session = request.getSession(); //等價於request.getSession()

session超時

  伺服器會將空閒時間過長的session物件刪除掉,這樣做是為了節省記憶體空間的佔用。伺服器預設的超時時間一般是30分鐘。可以通過setMaxInactiveInterval(int seconds)來設定兩次請求之間的最大時間間隔,也可看成是失效時間,如果超過這個失效時間,則伺服器會銷燬這個session物件。

使用session場景

比如登陸控制,在登陸成功後,將一些資料繫結到session物件上,如:

session.setAttribute("user",user);

當使用者請求要保護的資源(只有登陸成功才能訪問的資源)時候,進行session驗證:

Object obj = session.getAttribute("user");
if(obj == null){//沒有登陸,重定向到登陸頁面
    response.sendRedirect("login.jsp)";
}

 

注:以上關於session和cookie的demo是在tomcat容器下測試的

相關文章