1. 程式人生 > >【Web 服務】深入理解無狀態協議、HTTP 與 web 會話

【Web 服務】深入理解無狀態協議、HTTP 與 web 會話

1. 什麼是狀態(state)?

狀態可以簡單地理解為事物在某一個時間點上的特徵表現。事物在不斷的發展、運動和變化,這樣才會有狀態,這樣的狀態才會有意義!絕對的靜止就是黑洞,就不會有狀態,也不會產生資訊!

生老病死,花開花謝,春去秋來,都是事物狀態的變遷! 在這裡插入圖片描述

軟體領域與狀態相關的概念有很多,比如生命週期,狀態機,狀態遷移,無狀態服務,無狀態協議,等等。 在這裡插入圖片描述

2. 無狀態協議(Stateless protocol)

通訊協議分為有狀態(stateful)協議和無狀態(stateless)協議,無狀態協議不儲存互動資訊,通訊中的一方不關心另一方的狀態,也無需對結果進行確認。比如 UDP 協議就是無狀態,TCP 協議就是有狀態;HTTP 是無狀態的,FTP,SSH 是有狀態的。

無狀態(stateless) vs 無會話(no session) vs 無連線(connectionless)——這三個概念本質上講的是同一件事,只是層次和關注點不同而已。會話是應用或服務層面的概念,指代服務執行的上下文;連線是資料傳輸的通道,面向連線/無連線則表明了連線的特點。

比如 TCP 是面向連線的有狀態協議,其“可靠性傳輸”的本質就是一種形式會話管理。

3. 無狀態的特徵

無狀態設計能大大的簡化伺服器的複雜性,因為狀態管理是一件複雜的事情,要建立連線,建立會話,同步資訊,釋放資源,異常與錯誤處理等等。而無狀態就簡單多了,一件是一件,一碼歸一碼。

但要保證請求的獨立性,就必須在請求體中攜帶該請求所需的全部資訊,服務端解析請求資訊,處理並相應。

設計的本質就是取捨,在時間空間之間取捨,在 CPUIO 之間取捨,在之間取捨,在效率成本之間取捨…

當網路頻寬是通訊的最大瓶頸時,設計人員關注的重點是如何對資訊進行編碼,進行壓縮,絞盡腦汁的篩除掉資訊中的冗餘資料,那個時代的通訊協議,每個位元都要發揮它的價值。當頻寬無線富足時,設計人員就慢慢將關注點轉移到業務上,轉移到開發效率上。

4. HTTP

HTTP 是典型的無狀態協議,每個 HTTP 請求都是獨立的,隔離的,自解釋的! 在這裡插入圖片描述 簡單地說,就是 HTTP 協議本身不支援 Session,是無狀態的,不需要登入。FTP 協議就是有狀態的,在資訊互動之前要登入,建立本次互動對應的會話,還可以進行認證、鑑權等。

在這裡插入圖片描述

每一個 HTTP 請求(非長連線模式),都包含連線的建立和關閉。

但這並不意味著 HTTP Server 只能提供無狀態的服務!IP 協議是無狀態的,但基於 IP 的 TCP 就是有狀態的。協議棧,或者服務棧,都是層次化的,在無狀態協議上新增新的會話機制,便可以提供有狀態的服務。

5. Web 會話

在網際網路時代,我們每時每刻都在與 Web 伺服器打交道,有些服務是有狀態的,有些是無狀態的。這裡涉及到了兩個問題,一是 Web 服務需不需要會話?二是如何實現 Web 會話。

不同的場景,有不同的需求;不同的需求,會產生不同的方案!比如我百度或谷歌一下,這個需求本身是無狀態的。我搜索一下喜馬拉雅山的高度,難道你還要問我是哪裡人?多大了?姓甚名誰?那不就搞笑了嗎!當然從百度的角度看,為了優化搜尋,或者廣告推廣,即使客戶沒有會話需求,百度在後臺也默默的進行會話管理。

另外,有些服務是有狀態的,比如去視訊網站看電影,vip 會員免廣告,這就涉及到會話了,你不登入/認證/鑑權,人家怎麼知道你是不是會員呢?

在這裡插入圖片描述

總體而言,3 種常見的實現 Web 應用會話管理的方式:

  1. 基於 server 端 session 的管理方式: JSESSIONID,PHPSESSIONID
  2. cookie-base的管理方式
  3. token-base的管理方式

Web Session 是建立在 HTTP 層之上的服務管理機制,在實現 Session 機制時,必然會用到 HTTP 的某些特性,比如 cookie, 當然也可以實現不依賴於 cookie 的 Session 機制,尤其是 cookie 有可能會被人為的禁止;另一種技術是 URL 重寫技術,就是把 session id 直接附加在 URL 路徑的後面。

在設計會話管理的機制中,常常要考慮會話資源的記憶體消耗,分散式與叢集部署時的資料共享,跨域,服務端複雜性,資訊傳輸的安全性等問題。

Web Session 是伺服器的機制,沒有統一的規範,不同的 Web 伺服器有不同的實現。Java 的 Servlet,Python 的 wsgi,以及 CGI 都有各自關於 Session 管理的規範。

5. 會話,登入,認證

有狀態的服務一定有會話管理,但不一定需要登入。 會話管理是登入與認證的前提和基礎。

一些相關的概念:

  1. 身份識別: identify,登入與認證/鑑權,第三方登入
  2. 會話: session
  3. 認證: authenticate,
  4. 單點登入: sso
  5. CAS:Apache 認證服務解決方案
  6. SAML
  7. OAuth2.0
  8. AAA

無論是 Web 端還是移動端,第三方應用賬戶登入已經成為了標配。

實現單點登入,分為兩個階段:

  1. 階段一:所有子系統共享使用者身份資訊,也就是所有的身份資訊都儲存在同一處,比如 ldap server,或者某個資料庫中,那麼可以使用同一賬戶登入所有的子系統。本公司的 jira,郵件系統,OA,日誌,SVN … 所有的賬戶資訊都是獨立的,更無需談論什麼單點登入了。
  2. 階段二: 只要登入了任意一個子系統,再訪問其它子系統時,就無需登入了,此之謂單點登入。

單點登入的三駕馬車: OpenID, OAuth, SAML

OpenID

Google, Yahoo, PayPal 等支援 OpenID, OpenID-Connect 是認證協議。 使用場景: 商用應用的單點登入

OAuth2

其實是個授權的標準協議,也可以認為是基於授權的“偽認證”。 使用場景: API 授權

SAML

  1. Security Assertion Markup Language
  2. 可用於單點登入
  3. IDP: Identity Provider, 身份鑑別伺服器,主站
  4. SP: Service Providers, 在主站中註冊過的應用伺服器

使用場景: 企業級單點登入,但是對於移動端支援不是很好