1. 程式人生 > 實用技巧 >客戶端識別與cookie機制(HTTP權威指南)

客戶端識別與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 瀏覽器為例:

Cookie 的屬性
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 事務總是要求使用伺服器證書的。