客戶端識別與cookie機制(HTTP權威指南)
一、客戶端識別
每天都有數以億計的客戶端與Web伺服器通訊,伺服器是怎麼知道它在和誰對話呢?
- 承載使用者身份資訊的HTTP首部
- 客戶端 IP,通過使用者的 IP 地址對其進行識別
- 使用者登入,用認證的方式識別使用者
- 胖 URL,在 URL 中嵌入識別資訊的技術
- cookie
承載使用者資訊的首部有 From(使用者的E-mail地址)、Authorization、Client-IP、Cookie。
以 From 為例,每個使用者都有不同的郵箱地址,按理來說是可以標識使用者的,但為什麼不用呢?
Web 伺服器並不都是善意的,有些惡意伺服器會收集這些郵箱,然後傳送令人厭惡的廣告,另外也是不安全的。
然後是客戶端 IP 也就是 Client-IP 首部,這個很容易想到,一個 IP 只能代表一個客戶端,不能代表使用者。
再然後就是使用者登入,也就是 Authorization 首部,這裡詳細說一下:
當用戶訪問一個資源時,比如個人資訊,這時伺服器就會要求使用者登入,輸入使用者名稱和密碼等資訊。
只要使用者輸入了使用者名稱和密碼,瀏覽器就會重複原請求,並新增 Authorization 首部,值為使用者名稱和密碼的 Base64 加密。
今後的請求要登入時,瀏覽器就會把 Authorization 首部及其值傳送出去。甚至沒要求登入時也會發送出去。
以上談到 Authorization 的值為 Base64 加密,該加密是可逆的,所以並不安全。
什麼是胖 URL 呢?舉個例子吧:
<a href="/exec/obidos/tg/browse/-/229220/ref=gr_gifts/002-114565-8016838">All Gifts</a>
比如上面的 002-114565-8016838 就是一個標識碼,每個使用者訪問都不同。這就被稱為胖 URL。
這種方式有很明顯的缺點:醜陋、該 URL 不可以共享,否則將會洩漏個人資訊、沒有公共的快取、伺服器要重寫 HTML增加負荷......
二、Cookie
好啦,下面重點來了,cookie 是當前識別使用者並實現持久會話的最好方式,我們來介紹一下它:
可以籠統的將 cookie 分為兩類:會話 cookie 和 持久 cookie。
會話 cookie 是一種臨時 cookie,使用者退出瀏覽器時,會話 cookie 就被刪除了。
持久 cookie 儲存在硬碟上,瀏覽器退出,計算機重啟時它仍在,不過它有一個過期時間。
如果設定了 Discard 引數,或者沒有設定 Expires 或 Max-Age 引數來說明擴充套件的過期時間,這個 cookie 就是會話 cookie。
同胖 URL 思路一樣,也是給訪問的使用者打上一個標籤。cookie 中包含了一個由 name=value 這樣資訊構成的任意列表。
並通過 Set-Cookie 或 Set-Coookie2 HTTP響應(擴充套件)首部將其貼到使用者身上去。
以 Google 瀏覽器為例:
Name | cookie 的名字 |
Value | cookie 的值 |
Domain | cookie 的域,那些站點可以看到 cookie |
Path | 域中與 Cookie 相關的路徑字首,那些域字首可以看到 cookie |
Expires/Max-Age | Expires 是過期日期,Max-Age 是過期剩餘秒數 |
Size | 此 cookie 的大小,不知道怎麼算的哈 |
HttpOnly | 是否 js 指令碼可以讀取該 cookie |
Secure | 是否只有在使用 SSL 連線時才傳送這個 cookie |
SameSite | 用來防止 CSRF 攻擊和使用者追蹤 |
Priority | cookie 的優先順序,當 cookie 數量超出時,優先順序最低的會被刪掉 |
以上屬性需要詳細解釋一下的就是 Domain 和 Path:
瀏覽器內部的 cookie 罐中可以有成百上千個 cookie,但瀏覽器不會將每個 cookie 都發送給所有的站點。
總之,瀏覽器只向伺服器傳送伺服器產生的那些 cookie。
1、Domain 屬性
比如下面這個HTTP響應首部就是告訴瀏覽器將 cookie user="mary17" 傳送給域 “.airtravelbargains.com” 中的所有站點。
Set-cookie: user="mary17"; domain="airtravelbargains.com"
如果使用者訪問的是 www.airtravelbargains.com、specials.airtravelbargains.com 或任意以 .airtravelbargains.com 結尾的結點,
Cookie: user="mary17" 都會被髮布出去。
2、Path 屬性
例如,某個 Web 伺服器可能是兩個組織共享的,每個組織都有獨立的 cookie。
Set-cookie: pref=compact; domain="airtravelbargains.com"; path="/autos/"
如果使用者訪問 http://www.airtravelbargains.com/specials.html,就只會獲得這個 cookie: Cookie: user="mary17"
如果使用者訪問http://www.airtravelbargains.com/autos/cheapo/index.html,就會獲得兩個 cookie:
Cookie: user="mary17"
Cooke: pref="compact"
3、Cookie 有兩個版本:Set-cookie、Set-cookie2,區別就是首部的 Name 不同,還有就是後者屬性更多一些。
三、安全 HTTP
HTTPS 是最流行的 HTTP 安全形式,HTTPS 的 URL 是以 https://,而不是 http:// 開頭。
使用 HTTPS 時,所有的 HTTP 請求和響應資料在傳送到網路之前,都要進行加密。
HTTPS 在 HTTP 下面提供了一個傳輸級的密碼安全層,可以使用 SSL,也可以使用 TLS(TLS 是 SSL 的升級版)。
大部分困難的編碼以及解碼工作都是在安全層完成的,所以 Web 客戶端和伺服器無需過多的修改其協議處理邏輯。
四、密碼
任意兩人之間要進行私密通訊,都需要一個只有彼此才能理解的語言。
比如迴圈移位(n) 編碼器:
// 金鑰=1,右移1位
明文:Meet me at the pier at midnight。
密文:nffu nf bu uif qjfs bu njeojhiu。
// 金鑰=2,右移2位
明文:Meet me at the pier at midnight。
密文:oggv og cv vig rkgt cv okfpkijv。
// 金鑰=3,右移3位
明文:Meet me at the pier at midnight。
密文:phhw ph dw wkh slhu dw plgqlijkw。
給定一段明文報文 P、一個編碼函式 E 和一個數字編碼金鑰 e,就可以生成一段經過編碼的密文 C。
通過解碼函式 D 和解碼金鑰 d,就可以將密文 C 解碼為原始的明文 P。
1、對稱金鑰加密技術
對稱金鑰加密技術是指,編碼時和解碼時的金鑰時一樣的,常見的有 DES、RC2、RC4。
缺點:如果很多人要和 web 站點通訊,那每個人和 web 站點都要建立一個私有金鑰,數量將是很龐大的。
2、公開金鑰加密技術
公開金鑰加密技術沒有為每對主機使用單獨的加密/解密金鑰,而是使用了兩個非對稱金鑰,常見的有 RSA。
一個用來對主機報文編碼,一個用來對主機報文解碼。編碼金鑰是眾所周知的,但是隻有主機才知道私有的解密金鑰。
五、數字簽名
數字簽名是附加在報文上特殊加密效驗,用來說明是誰編寫的報文,同時證明報文未被篡改過。
數字簽名通常是用非對稱公開金鑰技術產生的。因為只有所有者才知道其私有金鑰,所有可以將作者的私有金鑰當作一種指紋使用。
六、數字證書
典型的數字證書如下格式:
證書版本號 -----------------------|
證書序列號 -----------------------|
證書籤名演算法 --------------------|
證書頒發者 ---------------------------》 數字簽名函式
有效期 -----------------------------| |
物件名稱 --------------------------| |
物件公開金鑰 --------------------| |
其他擴充套件資訊 --------------------| |
數字簽名 《---------------------------------------|
通過 HTTPS 建立了一個安全 Web 事務後,現代瀏覽器都會自動獲取所連線伺服器的數字證書。
如果伺服器沒有證書,安全連線就會失敗。
七、HTTPS 細節介紹
HTTPS 就是在安全的傳輸層上傳送的 HTTP,安全層是通過 SSL 或其替代協議 TLS 來實現的。
URL 為 http 開頭的,預設情況下客戶端會開啟一條到伺服器 80 埠的連線。
URL 為 https 開頭的,預設情況下客戶端會開啟一條到伺服器 443 埠的連線。
如果沒有安全層,HTTP 的傳輸時非常簡單的,在建立連線後,傳送一條請求報文,接收一條響應報文,最後關閉連線就完事了。
因為有了安全層,建立連線後,客戶端和伺服器就會初始化 SSL\TSL 層,對加密引數進行溝通,互換金鑰。
SSL握手完成後,SSL 初始化就完成了,客戶端就可以把請求報文傳送給安全層了,在將這些報文傳送給 TCP 之前,要對其進行加密。
SSL握手的過程:1、交換協議版本號,2、選擇一個兩端都瞭解的密碼,3、對兩端身份進行認證,4、生成臨時會話金鑰,加密通道。
SSL 支援雙向認證,將伺服器證書承載回客戶端,再將客戶端證書回送給伺服器。
但是瀏覽時並不經常使用客戶端證書,大部分使用者甚至都沒有自己的客戶端證書,但是安全 HTTPS 事務總是要求使用伺服器證書的。