關於HTTP中cookie 和session機制

來源:互聯網
上載者:User

標籤:實現   開始   就會   set   機制   處理   儲存   網域名稱   display   

前言

Cookie是由網景公司的前僱員Lou Montulli 在1993年發明的。向前輩致敬。

1. Cookie和Session介紹

    Cookie 和Session 是為了在無狀態下HTTP協議之上維護工作階段狀態,使得伺服器可以知道當前適合哪個客戶在打交道。因為HTTP協議是無狀態的,即每次使用者請求到達伺服器時,HTTP伺服器並不知道這個使用者是誰、是否登入過等。現在的伺服器之所以知道我們是否已經登入,是因為伺服器在登入時設定了瀏覽器的Cookie!Session則是藉由Cookie而實現的更高層的伺服器與瀏覽器之間的會話。

2. Cookie的實現機制

   Cookie是由用戶端儲存的小型文字檔,其內容為一系列的索引值對。Cookie是由HTTP伺服器設定的,儲存在瀏覽器中,在使用者訪問其他頁面時,會在HTTP請求中附上該伺服器之前設定的Cookie。Cookie的實現標準定義在RFC2109:HTTP State Management Mechanism中,那麼Cookie是怎麼工作的呢?下面給出整個Cookie的傳遞流程:

    1.  瀏覽器(或者用戶端)向某個URL發起HTTP請求(可以是任何請求,比如GET一個頁面、POST一個登入表單等)

    2.  對應的HTTP伺服器收到該HTTP請求,並計算應當返回給瀏覽器的HTTP響應。_ps_HTTP響應包括要求標頭和請求體兩部分。

    3.  在回應標頭加入Set-Cookie欄位,它的值是要設定的Cookie.

    4.  瀏覽器(或者用戶端)收到來自伺服器的HTTP響應。

    5.  瀏覽器在回應標頭中發現Set-Cookie欄位,就會將該欄位的值儲存在記憶體或者硬碟中。Set-Cookie 欄位的值可以是很多項Cookie,每一項都可以指定到期的

       時間Expires。預設的到期時間是使用者關閉瀏覽器時。

    6.  瀏覽器下次給該伺服器發送HTTP請求時,會將伺服器設定的Cookie附加在HTTP請求的頭欄位Cookie中。瀏覽器可以儲存多個網域名稱下的Cookie,但只發送當前

       請求的網域名稱曾指定的Cookie,這個網域名稱也可以在set-Cookie欄位中指定。

    7.  伺服器收到這個HTTP請求,發現要求標頭中有Cookie欄位,便知道之前就和這個使用者打過交道了。這樣就辨別了瀏覽器(或者用戶端)。

    8.  到期的Cookie會被瀏覽器(或者用戶端)刪除。

   總之,伺服器通過Set-Cookie回應標頭欄位來指示瀏覽器儲存Cookie,瀏覽器通過Cookie要求標頭欄位來告訴伺服器之前的狀態。Cookie中包含若干個索引值對,每個索引值對都可以設定到期時間。3. Cookie的安全隱患

  Cookie提供了一種手段使得HTTP請求可以附加當前的狀態,現在的網站也是靠Cookie來標識使用者的登入狀態的:

    1.  使用者提交使用者名稱和密碼的表單,這通常是一個POST HTTP 要求。

    2.  伺服器驗證使用者名稱和密碼,如果合法則返回200(OK)並設定Set-Cookie 為 authed = ture 。

    3.  瀏覽器儲存該Cookie。

    4.  瀏覽器發送請求時,設定Cookie欄位為authed = ture。

    5.   伺服器收到第二次請求,從Cookie欄位得知該使用者已經登入。按照已登入使用者的許可權來處理此次請求

  這裡面存在的問題在哪?

      我們知道可以發送HTTP請求的不只是瀏覽器,很多HTTP用戶端軟體也可以發送任意的HTTP請求,可以設定任何頭欄位。假如我們直接設定Cookie欄位為authed = true

      並發送該HTTP請求,伺服器豈不是被欺騙了?這種攻擊非常容易,Cookie是可以被篡改的!

4. Cookie防篡改機制 

 伺服器可以為每個Cookie項產生簽名,由於使用者篡改Cookie後無法產生對應的簽名, 伺服器便可以得知使用者對Cookie進行了篡改。一個簡單的校正過程可能是這樣的:

  1. 在伺服器中配置一個不為人知的字串(我們叫它Secret),比如:x$sfz32。
  2. 當伺服器需要設定Cookie時(比如authed=false),不僅設定authed的值為false, 在值的後面進一步設定一個簽名,最終設定的Cookie是authed=false|6hTiBl7lVpd1P。
  3. 簽名6hTiBl7lVpd1P是這樣產生的:Hash(‘x$sfz32‘+‘true‘)。 要設定的值與Secret相加再取雜湊。
  4. 使用者收到HTTP響應並發現頭欄位Set-Cookie: authed=false|6hTiBl7lVpd1P。
  5. 使用者在發送HTTP請求時,篡改了authed值,設定頭欄位Cookie: authed=true|???。 因為使用者不知道Secret,無法產生簽名,只能隨便填一個。
  6. 伺服器收到HTTP請求,發現Cookie: authed=true|???。伺服器開始進行校正: Hash(‘true‘+‘x$sfz32‘),便會發現使用者提供的簽名不正確。

通過給Cookie添加簽名,使得伺服器得以知道Cookie被篡改。然而故事並未結束,這樣還是不安全。 因為Cookie是明文傳輸的, 只要伺服器設定過一次authed=true|xxxx我不就知道true的簽名是xxxx了麼, 以後就可以用這個簽名來欺騙伺服器了。因此Cookie中最好不要放敏感性資料。 一般來講Cookie中只會放一個Session Id,而Session儲存在伺服器端

 5. Session的實現機制

    Session是儲存在伺服器端的,避免了在用戶端Cookie中儲存敏感性資料。Session可以儲存在HTTP伺服器的記憶體中,也可以存在資料庫中,對於重量級的應用甚至可以

  儲存在資料庫中。我們以儲存在redis中的Session為例,來考察如何驗證使用者登入狀態的問題。

    1.  使用者提交包含使用者名稱和密碼的表單,發送HTTP請求。

    2.  伺服器驗證使用者發來的使用者名稱和密碼

    3.  如果正確則把目前使用者名(通常是使用者物件)儲存到redis中,並產生它在redis中的ID。 這個ID稱為Session ID,通過Session ID可以從Redis中取出對應的使用者

       對象, 敏感性資料(比如authed=true)都儲存在這個使用者物件中。

    4.  設定Cookie為sessionId=xxxxxx|checksum並發送HTTP響應, 仍然為每一項Cookie都設定簽名。

    5.  使用者收到HTTP響應後,便看不到任何敏感性資料了。在此後的請求中發送該Cookie給伺服器。

    6.  伺服器收到此後的HTTP請求後,發現Cookie中有SessionID,進行放篡改驗證。

    7.  如果通過了驗證,根據該ID從Redis中取出對應的使用者物件, 查看該對象的狀態並繼續執行商務邏輯。

   Web應用程式框架都是實現上述過程,在Web應用中可以直接擷取目前使用者。相當於在HTTP協議之上,通過Cookie實現了持久的會話。這個會話便稱為Session。

 

關於HTTP中cookie 和session機制

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.