Cookie和Session

在計算機網中經常會聽到這兩個專業術語,通常簡單的認識是Cookie能夠保存用戶登錄某個網站的帳號和密碼,Session最經典的就是保存購物車中的信息,這一點認識確定是很膚淺的。html

  1. cookie 存儲在瀏覽器(有大小限制),session 存儲在服務端(沒有大小限制)
  2. 一般 session 的實現是基於 cookie 的,即 session id 存儲於 cookie 中

 

這裏我採集了網上我我的認爲講授的很是好的大佬們的幾個觀點。java

 

1.

1. 因爲HTTP協議是無狀態的協議,因此服務端須要記錄用戶的狀態時,就須要用某種機制來識具體的用戶,這個機制就是Session.典型的場景好比購物車,當你點擊下單按鈕時,因爲HTTP協議無狀態,因此並不知道是哪一個用戶操做的,因此服務端要爲特定的用戶建立了特定的Session,用用於標識這個用戶,而且跟蹤用戶,這樣才知道購物車裏面有幾本書。這個Session是保存在服務端的,有一個惟一標識。在服務端保存Session的方法不少,內存、數據庫、文件都有。集羣的時候也要考慮Session的轉移,在大型的網站,通常會有專門的Session服務器集羣,用來保存用戶會話,這個時候 Session 信息都是放在內存的,使用一些緩存服務好比Memcached之類的來放 Session。node

2. 思考一下服務端如何識別特定的客戶?這個時候Cookie就登場了。每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用 Cookie 來實現Session跟蹤的,第一次建立Session的時候,服務端會在HTTP協議中告訴客戶端,須要在 Cookie 裏面記錄一個Session ID,之後每次請求把這個會話ID發送到服務器,我就知道你是誰了。有人問,若是客戶端的瀏覽器禁用了 Cookie 怎麼辦?通常這種狀況下,會使用一種叫作URL重寫的技術來進行會話跟蹤,即每次HTTP交互,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。web

3. Cookie其實還能夠用在一些方便用戶的場景下,設想你某次登錄過一個網站,下次登陸的時候不想再次輸入帳號了,怎麼辦?這個信息能夠寫到Cookie裏面,訪問網站的時候,網站頁面的腳本能夠讀取這個信息,就自動幫你把用戶名給填了,可以方便一下用戶。這也是Cookie名稱的由來,給用戶的一點甜頭。因此,總結一下:Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中;Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。
算法

4.若是cookie裏的sessionid被其餘人發現了,好比連了不安全的 Wi-Fi ,Cookie 可能會被竊取,而後模擬用戶操做。數據庫

5.有人疑問:既然session仍是須要用到cookie,那爲何不直接就用cookie來識別用戶呢。貌似是由於cookies明文保存,很是不安全。並且cookies只能保存文本,長度有限,session保存在服務器端相對安全並且能夠存儲很是多的內容express

 

2.

1,session 在服務器端,cookie 在客戶端(瀏覽器)
 
2,session 默認被存在在服務器的一個文件裏(不是內存)

3,session 的運行依賴 session id,而 session id 是存在 cookie 中的,也就是說,若是瀏覽器禁用了 cookie ,同時 session 也會失效(可是能夠經過其它方式實現,好比在 url 中傳遞 session_id)

4,session 能夠放在 文件、數據庫、或內存中均可以。

5,用戶驗證這種場合通常會用 session 所以,維持一個會話的核心就是客戶端的惟一標識,即 session id

6 , 這裏能夠在瞭解下token,連接:http://www.jianshu.com/p/3e3d9c5a4eaf
 
7.好像nodejs的express的,就是默認放在內存裏的。去掉默認,而後改爲能夠放在文件、數據庫、內存,就行了?
 
 

3.

原文地址:
https://www.zhihu.com/question/19786827/answer/66706108

這個大佬說的很詳細,可是好像有些地方仍是有點爭議。。。
--------------------分割線----------------------------------------------------------------------------------------------------------
 
COOKIE和SESSION有什麼區別?
cookie保存在客戶端,session保存在服務器端,
cookie目的能夠跟蹤會話,也能夠保存用戶喜愛或者保存用戶名密碼
session用來跟蹤會話


①當咱們登陸網站勾選保存用戶名和密碼的時候,通常保存的都是cookie,將用戶名和密碼的cookie保存到硬盤中,這樣再次登陸的時候瀏覽器直接將cookie發送到服務端驗證,直接username和password保存到客戶端,固然這樣不安全,瀏覽器也能夠加密解密這樣作,每一個瀏覽器均可以有本身的加密解密方式,這樣方便了用戶,再好比用戶喜歡的網頁背景色,好比QQ空間的背景,這些信息也是能夠經過cookie保存到客戶端的,這樣登陸以後直接瀏覽器直接就能夠拿到相應的偏好設置。

②跟蹤會話,好比某些網站中網頁有不一樣的訪問權限,有隻能登陸的用戶訪問的網頁或者用戶級別不一樣不能訪問的,可是http請求是無狀態的,每次訪問服務端是不知道是不是登陸用戶,很天然的想到在http請求報文中加入登陸標識就能夠了,這個登陸標識就能夠是cookie,這樣的cookie服務端要保存有全部登陸用戶的cookie,這樣請求報文來了以後拿到登陸標識cookie,在服務端進行比較久能夠了。再好比購物網站,屢次點擊添加商品到購物車客戶端很容易知道哪些物品在購物車中,可是服務端怎麼知道每次添加的物品放到哪一個登陸用戶的購物車中呢?也須要請求報文中帶着cookie才行(在不登錄的狀況下京東也是能夠不斷添加商品的,推測應該是登陸的時候一併建立cookie而且發送物品信息),這些cookie都是爲了跟蹤會話用的,因此客戶端有,服務端也有,而且服務端有所有的會話cookie。

後面衍生出session技術,session技術是要使用到cookie的,之因此出現session技術,主要是爲了安全。

http是無狀態的協議,客戶每次讀取web頁面時,服務器都打開新的會話,並且服務器也不會自動維護客戶的上下文信息,那麼要怎麼才能實現網上商店中的購物車呢,session就是一種保存上下文信息的機制,它是針對每個用戶的,變量的值保存在服務器端,經過SessionID來區分不一樣的客戶,session是以cookie或URL重寫爲基礎的,默認使用cookie來實現,系統會創造一個名爲JSESSIONID的輸出cookie,咱們叫作session cookie,以區別persistent cookies,也就是咱們一般所說的cookie,注意session cookie是存儲於瀏覽器內存中的,並非寫到硬盤上的,這也就是咱們剛纔看到的JSESSIONID,咱們一般情是看不到JSESSIONID的,可是當咱們把瀏覽器的cookie禁止後,web服務器會採用URL重寫的方式傳遞Sessionid,咱們就能夠在地址欄看到 sessionid=KWJHUG6JJM65HS2K6之類的字符串。瀏覽器

你們請看在HTTP請求報文頭的最後一行有cookie,不過是JSessionID的cookie值緩存


Cookie: $Version=1; Skin=new;jsessionid=5F4771183629C9834F8382E23BE13C4C安全

好比前兩個值,應該屬於偏好設置之類的。


服務端是怎麼知道客戶端的多個請求是隸屬於一個Session呢?注意到後臺的那個jsessionid=5F4771183629C9834F8382E23BE13C4C木有?原來就是經過HTTP請求報文頭的Cookie屬性的jsessionid的值關聯起來的!(固然也能夠經過重寫URL的方式將會話ID附帶在每一個URL的後面哦)。
明白了原理,咱們就能夠很容易的分辨出persistent cookies和session cookie的區別了,網上那些關於二者安全性的討論也就一目瞭然了,session cookie針對某一次會話而言,會話結束session cookie也就隨着消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本(一般是加密的),並且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,天然不如 session cookie安全了。


一般session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣咱們信息共享的目的就達不到了,此時咱們能夠先把sessionid保存在persistent cookie中,而後在新窗口中讀出來,就能夠獲得上一個窗口SessionID了,這樣經過session cookie和persistent cookie的結合咱們就實現了跨窗口的session tracking(會話跟蹤)。
在一些web開發的書中,每每只是簡單的把Session和cookie做爲兩種並列的http傳送信息的方式,session cookies位於服務器端,persistent cookie位於客戶端,但是session又是以cookie爲基礎的,明白的二者之間的聯繫和區別,咱們就不難選擇合適的技術來開發web service了。


部分參考自: session與cookie的區別

===================分割線==============
舉個QQ空間的例子:
① 當咱們登陸QQ空間的時候,能夠選擇保存用戶名和密碼,這樣下次登陸的時候瀏覽器能夠自動填充或者自動登錄,此時使用的是cookie技術,將於
http://qzone.qq.com/
域名對應的cookie保存到硬盤中,下次訪問的時候瀏覽器查找保存在硬盤中的與該域名對應的cookie填充。

②登陸以後,咱們可能作些操做,好比刪除日誌,發表說說,這些只有登陸用戶才能作的事情可使用cookie也可使用session進行會話跟蹤

③空間的喜愛設置能夠保存到硬盤cookie當中。

-------------------------------------------------------------------------------------------------------------------------
其實說白了session就是用來保存會話的cookie。
下面介紹下Java中Servlet的session管理
http://lavasoft.blog.51cto.com/62575/275589  深刻理解HTTP Session

session在web開發中是一個很是重要的概念,這個概念很抽象,很難定義,也是最讓人迷惑的一個名詞,也是最多被濫用的名字之一,在不一樣的場合,session一次的含義也很不相同。這裏只探討HTTP Session。

爲了說明問題,這裏基於Java Servlet理解Session的概念與原理,這裏所說Servlet已經涵蓋了JSP技術,由於JSP最終也會被編譯爲Servlet,二者有着相同的本質。

在Java中,HTTP的Session對象用javax.servlet.http.HttpSession來表示。

一、概念:Session表明服務器與瀏覽器的一次會話過程,這個過程是連續的,也能夠時斷時續的。在Servlet中,session指的是HttpSession類的對象,這個概念到此結束了,也許會很模糊,但只有看完本文,才能真正有個深入理解。

二、Session建立的時間是:
一個常見的誤解是覺得session在有客戶端訪問時就被建立,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被建立,注意若是JSP沒有顯示的使用 <% @page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷。
因爲session會消耗內存資源,所以,若是不打算使用session,應該在全部的JSP中關閉它。

引伸:
1)、訪問*.html的靜態資源由於不會被編譯爲Servlet,也就不涉及session的問題。
2)、當JSP頁面沒有顯式禁止session的時候,在打開瀏覽器第一次請求該jsp的時候,服務器會自動爲其建立一個session,並賦予其一個sessionID,發送給客戶端的瀏覽器。之後客戶端接着請求本應用中其餘資源的時候,會自動在請求頭上添加:
Cookie:JSESSIONID=客戶端第一次拿到的session ID
這樣,服務器端在接到請求時候,就會收到session ID,並根據ID在內存中找到以前建立的session對象,提供給請求使用。這也是session使用的基本原理----搞不懂這個,就永遠不明白session的原理。
下面是兩次請求同一個jsp,請求頭信息:

經過圖能夠清晰發現,第二次請求的時候,已經添加session ID的信息。
三、Session刪除的時間是:
1)Session超時:超時指的是連續必定時間服務器沒有收到該Session所對應客戶端的請求,而且這個時間超過了服務器設置的Session超時的最大時間。
2)程序調用HttpSession.invalidate()
3)服務器關閉或服務中止

四、session存放在哪裏:服務器端的內存中。不過session能夠經過特殊的方式作持久化管理。

五、session的id是從哪裏來的,sessionID是如何使用的:當客戶端第一次請求session對象時候,服務器會爲客戶端建立一個session,並將經過特殊算法算出一個session的ID,用來標識該session對象,當瀏覽器下次(session繼續有效時)請求別的資源的時候,瀏覽器會偷偷地將sessionID放置到請求頭中,服務器接收到請求後就獲得該請求的sessionID,服務器找到該id的session返還給請求者(Servlet)使用。一個會話只能有一個session對象,對session來講是隻認id不認人。

六、session會由於瀏覽器的關閉而刪除嗎?
不會,session只會經過上面提到的方式去關閉。

七、同一客戶端機器屢次請求同一個資源,session同樣嗎?
通常來講,每次請求都會新建立一個session。


其實,這個也不必定的,總結下:對於多標籤的瀏覽器(好比360瀏覽器)來講,在一個瀏覽器窗口中,多個標籤同時訪問一個頁面,session是一個。對於多個瀏覽器窗口之間,同時或者相隔很短期訪問一個頁面,session是多個的,和瀏覽器的進程有關。對於一個同一個瀏覽器窗口,直接錄入url訪問同一應用的不一樣資源,session是同樣的。

八、session是一個容器,能夠存放會話過程當中的任何對象。

九、session由於請求(request對象)而產生,同一個會話中多個request共享了一session對象,能夠直接從請求中獲取到session對象。

十、其實,session的建立和使用總在服務端,而瀏覽器歷來都沒獲得過session對象。但瀏覽器能夠請求Servlet(jsp也是Servlet)來獲取session的信息。客戶端瀏覽器真正牢牢拿到的是session ID,而這個對於瀏覽器操做的人來講,是不可見的,而且用戶也無需關心本身處於哪一個會話過程當中。
---------------------------------------------------------------------------------------------------
好比下面一段使用session的代碼
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{

   response.setContentType("text/html");
   response.setCharacterEncoding("utf-8");
   PrintWriter out = response.getWriter();
   // 獲得用戶名和密碼,驗證
   String u = request.getParameter("username");
   String p = request.getParameter("password");

   UserBeanBO ubb = new UserBeanBO();
   if (ubb.checkUser(u, p))
   {
	// 1.把成功登錄的用戶全部信息放入session
	UserBean ub = ubb.getUserBean(u);
	request.getSession().setAttribute("userInfo", ub);
	// 2.把購物車的信息取出
	MyCartBO mcb = (MyCartBO)request.getSession().getAttribute("mycart");    
	ArrayList al = mcb.showMyCart();
	// 把al放入request
	request.setAttribute("mycartInfo", al);
	// 用戶合法
	request.getRequestDispatcher("success.jsp").forward(request,response);
  } else
  {
    // 用戶不合法
      request.getRequestDispatcher("error.jsp").forward(request, response);		  	
  }

}

HttpSession  javax.servlet.http.HttpServletRequest.getSession()

Returns the current session associated with this request, or if the request 
does not have a session, creates one.

Returns: the HttpSession associated with this request

See Also:

getSession(boolean)
javax.servlet.http.HttpServletRequest.getSession() 將會返回當前request相關聯的HttpSession對象,若是不存在,將會建立一個。 翻譯一下,當一個瀏覽器請求來到以後,Servlet處理程序(Servlet容器內部實現)將會主動檢查請求信息Cookie當中是否有JSESSIONID,如有,找到對應JSESSION的HttpSession對象,若是沒有,建立一個,具體的機制在Servlet容器的實現當中。
相關文章
相關標籤/搜索