Cookie&Session

Cookie&Sessionhtml

 

背景:Cookie和Session的原理、做用及如何設置和相關面試。java

1、誕生背景程序員

      HTTP是無狀態的,即服務器沒法知道兩個請求是否來自同一個瀏覽器,也就是服務器不知道用戶上一次作了什麼,每次請求都是徹底獨立的。面試

      早期互聯網只是用於簡單的瀏覽文檔信息、查看黃頁和門戶網站等,並無交互這個概念。可是隨着互聯網慢慢發展,寬帶、服務器等硬件設施獲得了不少的提高,互聯網容許人們作更多的事情,因此交互式Web(交互式Web即客戶端與服務器能夠互動,如用戶登陸、商品購買和論壇等)慢慢就興起了,而HTTP無狀態的特色對此形成了嚴重阻礙。瀏覽器

      因爲不能記錄用戶上次的操做,偉大的程序員發明了隱藏域用於記錄用戶上一次的操做信息;經過隱藏域把用戶上次操做記錄放在form表單的input中,這樣請求時將表單提交就能夠知道上一次用戶的操做了,可是這樣每次都得建立隱藏域並且須要賦值,既麻煩又容易出錯;可是隱藏域做用強大,時至今日都有不少人在用它解決各類問題。隱藏域的寫法以下:緩存

<input type="hidden" name="field_name" value="value">

      網景公司的盧-蒙特利Lou Montulli,在1994年將Cookies的概念應用於網絡通訊,用於解決用戶網上購物的購物車歷史記錄,而當時最強大的瀏覽器也是網景瀏覽器;以後在網景瀏覽器的支持下其餘瀏覽器也逐漸開始支持Cookie,到現在全部瀏覽器都支持Cookie了。安全

2、什麼是Cookie服務器

      Cookie的誕生是爲了解決HTTP無狀態的特性,用於知足交互式Web。cookie

圖1. Chrome瀏覽器百度首頁Cookies網絡

圖2. Firefox瀏覽器百度首頁Cookie

圖3. Safari瀏覽器百度首頁Cookie

      上圖中能夠看到在Chrome、Firefox和Safari瀏覽器中百度首頁的Cookie,在表格中,每一行都表明着一個Cookie。Cookie是由服務器發給客戶端的特殊信息,而這些信息以文本文件的形式存儲在客戶端,而後客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息,用於服務器記錄客戶端的狀態。

Cookie主要運用於如下三個方面:

一、會話狀態管理,如用戶登陸狀態、購物車、遊戲分數或其餘須要記錄的信息;

二、個性化設置,如用戶自定義設置、主題等;

三、瀏覽器行爲跟蹤。

3、Cookie原理

      Cookie是由服務器發出存儲在瀏覽器的特殊信息,其具體的過程能夠經過一個用戶登陸的例子來了解。

圖4. Cookie工做原理

如上圖所示,用戶在輸入用戶名和密碼以後,瀏覽器將用戶名和密碼發送給服務器,服務器進行驗證,驗證經過後將用戶信息加密後封裝成Cookie放在請求頭中返回給瀏覽器。

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg; Expires=Tue, 15 Aug 2019 21:47:38 GMT; Path=/; Domain=.169it.com; HttpOnly

[響應體]

瀏覽器收到服務器返回的數據,發現請求頭中有一個:Set-Cookie,而後它就把這個Cookie保存起來,下次瀏覽器再請求服務器的時候,會把Cookie也一塊兒放在請求頭中傳給服務器。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg

服務器收到請求後從請求頭中拿到Cookie,而後解析並獲得用戶信息,說明此用戶已登陸,所以Cookie是將數據保存在客戶端的。

      從上述用戶登陸的例子能夠看出,用戶信息是保存在Cookie中,也就至關因而保存在瀏覽器中的,那麼用戶就能夠隨意更改用戶信息,這是一種不安全的策略。另外,Cookie不管是服務器發送給瀏覽器,仍是瀏覽器發送給服務器,都是放在請求頭中的。

4、Cookie屬性

從上圖的Chorme、Firefox和Safari瀏覽器能夠看到一個Cookie有:Name、Value、Domian、Path、Expires/Max-Age、Size、Http(Httponly)和Secure這些屬性。

一、Name & Value

Name表示Cookie的名稱,服務器就是經過name屬性來獲取某個Cookie的值。

Value表示Cookie的值,多數狀況下服務器會把這個value當作一個Key去緩存中查詢保存的數據。

二、Domain & Path

Domian表示能夠訪問此Cookie的域名,下圖咱們以百度貼吧首頁的Cookie來了解下Domain的屬性。

圖5. Chrome瀏覽器貼吧首頁Cookie's Domain

      圖中能夠看出,第三列的Domian有:.baidu.com頂級域名和.teiba.baidu.com二級域名;因此這裏就有一個訪問規則:頂級域名只能設置或訪問頂級域名的Cookie,二級如下的域名只能訪問或設置自身或者頂級域名的Cookie,因此若是要在多個二級域名中共享Cookie的話,只能將Domain的屬性設置爲頂級域名。

Path表示能夠訪問此Cookie的頁面路徑;如path=/test,那麼只有/test路徑下的頁面能夠讀取此Cookie。

三、Expire/Max-Age

      Expire/Max-Age表示此cookie的超時時間;若設置其值爲一個時間,那麼當到達此時間後,此cookie則會失效;不設置的話默認值是Session,意思是cookie會和session一塊兒失效;當瀏覽器關閉(關閉整個瀏覽器,而不是瀏覽器的標籤頁)後,此cookie失效。另外,當Cookie的過時時間被設定時,設定的日期和時間只與客戶端相關,與服務端無關。

四、Size

Size表示Cookie的name+value的字符數,好比有一個Cookie:id=666,那麼Size=2+3=5。2便是name,3即爲value,各個瀏覽器對Cookie的支持都有所不一樣,以下圖:

圖6. 各瀏覽器Cookie支持的個數

五、HTTP

      HTTP表示cookie的httponly屬性;若此屬性爲true,則只有在http請求頭中會帶有此cookie的信息,而不能經過document.cookie來訪問此cookie。這麼設計是爲了提供一個安全措施來幫助阻止經過JavaScript發起的跨站腳本攻擊(XXS)竊取cookie的惡劣行爲。

圖7. document.cookie

六、Secure

Secure表示是否只能經過https來傳遞此條cookie;不像其餘選項,該選項只是一個標記而且沒有其餘的值。

5、Java操做Cookie

一、生成Cookie

 1 package com.ausclouds.bdbsec.auth.cmb;  2 
 3 import javax.servlet.http.Cookie;  4 import javax.servlet.http.HttpServlet;  5 import javax.servlet.http.HttpServletRequest;  6 import javax.servlet.http.HttpServletResponse;  7 
 8 public class CookieServlet extends HttpServlet {  9 
10  @Override 11     protected void service(HttpServletRequest req, HttpServletResponse resp){ 12         //建立Cookie對象
13         Cookie comCookie = new Cookie("computer", "HP"); 14         //服務器把cookie響應給客戶端,全部的cookie對象,都會在服務器端建立,經過http響應給客戶端(瀏覽器) 15 
16         //若是不設置使用時間,則取不到Cookie的值
17         comCookie.setMaxAge(60*60*24*30); 18 
19         //一旦設置了cookie的路徑,就只能經過這一個路徑才能獲取到cookie的信息
20         comCookie.setPath(req.getContextPath() + "/getCookie.sxt"); 21 
22         //添加cookie
23  resp.addCookie(comCookie); 24 
25  } 26 }

二、獲取Cookie

 1 package com.ausclouds.bdbsec.auth.cmb;  2 
 3 import javax.servlet.http.Cookie;  4 import javax.servlet.http.HttpServlet;  5 import javax.servlet.http.HttpServletRequest;  6 import javax.servlet.http.HttpServletResponse;  7 
 8 public class GetCookieServlet extends HttpServlet {  9 
10  @Override 11     protected void service(HttpServletRequest req, HttpServletResponse resp){ 12         //獲取cookie信息
13         Cookie[] cookies = req.getCookies(); 14         for (int i = 0; i<cookies.length; i++){ 15             System.out.println(cookies[i].getName() + ":" + cookies[i].getValue()); 16  } 17  } 18 
19 }

三、刪除Cookie

//刪除Cookie的思路就是替換原來的cookie,並設置它的生存時間爲0
Cookie cookie = new Cookie("Cookie",null);//cookie名字要相同
          cookie.setMaxAge(0); //               cookie.setPath(request.getContextPath());  // 相同路徑
              response.addCookie(cookie);

6、Session

一、誕生背景

      其實設計Cookie之初,它並非僅僅保存了一個key值,而是直接保存用戶的信息,可是因爲cookie是存在客戶端的,並且自己存儲的尺寸大小也是有限的,最關鍵的是用戶是可見的,而且能夠隨意地修改,這至關地不安全。爲了既安全又方便的讀取全局信息,因而誕生了Session這種新的存儲會話機制。

二、什麼是Session

      Session翻譯爲會話,服務器爲每一個瀏覽器建立一個會話對象,瀏覽器在第一次請求服務器時,服務器便會爲該瀏覽器生成一個Seesion對象,保存在服務端,而且把Session的Id以cookie的形式發送給客戶端瀏覽器,最終以用戶顯示結束或session超時爲結束。

Session工做原理:

1.當某個用戶向服務器發送第一個請求時,服務器爲其創建一個sesion,併爲此session建立一個標識號(sessionID);

2.這個用戶隨後的全部請求都應包括這個標識號(sessionID),服務器會校對這個標識號以判斷請求是屬於哪一個session的;

3.sessionID標識號有兩種實現方式:Cookie和URL重寫;

4.Cookie是將數據直接保存在客戶端,而Session是將數據保存在服務端,因此Session的安全性更佳。

圖8. Session工做原理(基於Cookie實現)

三、Java操做Session

1.建立Session

ActionContext actionContext = ActionContext.getContext(); Map<String, Object> mapSession = actionContext.getSession(); mapSession.put("branch", branch); mapSession.put("permission", per);

2.JSP獲取Session

1 if(session.getAttribute("branch") == null||session.getAttribute("permission") == null) 2  { 3  response.setCharacterEncoding("utf-8"); 4         out.print("<script>alert('您尚未登陸,請登陸') </script>"); 5  out.flush(); 6  out.close(); 7     }

3.Java後臺獲取Session

1 ActionContext actionContext = ActionContext.getContext(); 2 Map session = actionContext.getSession(); 3 String inputUserid =(String)session.get("username"); 4 String proving =(String)session.get("proving");

7、面試相關

一、Cookie和Session的關係?

1. 兩者都是爲實現客戶端與服務端交互而服務的;

2. Cookie是保存在客戶端,缺點易僞造、不安全;

3. Session是保存在服務端,會消耗服務器資源;

4. Session實現有兩種方式:Cookie和URL重寫。

二、Cookie帶來的安全性問題?

1. 會話劫持和XSS:在Web應用中,Cookie經常使用來標記用戶或受權會話。所以,若是Web應用的Cookie被竊取,可能致使受權用戶的會話受到攻擊;經常使用的竊取Cookie的方式有社會工程學攻擊和應用程序漏洞進行XSS攻擊;

2. 跨站請求僞造(CSRF):維基百科已經給出了一個較好的CSRF例子。如在不安全的聊天室或論壇上的一張圖片,它其實是一個給你銀行服務器發送提現的請求:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

當你點擊打開該圖片時,若是以前已經登陸過你的銀行帳號而且Cookie仍未失效,那麼你銀行裏的錢極可能會被自動轉走;解決CSRF的辦法有:隱藏域驗證碼、確認機制和設置較短的Cookie生命週期等。

三、Session應用場景?

Session主要是服務器端存儲,用來描述一些用戶信息或者相關的其餘數據,還能夠是其餘類型的數據,只要是你的業務以爲能夠綁定到用戶或客戶端的相關數據均可以放到session中;最基本的場景就是存儲登陸用戶信息。

四、Session生命週期?

一、建立:若訪問的第一個資源是JSP頁面,則建立session對象;若訪問的第一個資源是Servlet,則須要手動調用request.getSession()方法來建立session對象;

二、銷燬:調用session.invalidate()方法來銷燬session()對象,session會話超時默認30分鐘。

相關文章
相關標籤/搜索