程序員過關斬將--互聯網人必備知識cookie和session認證

程序員過關斬將--互聯網人必備知識cookie和session認證

菜菜,上次你說的cookie和session的文章,我覺得不太具體

那你想怎麼樣具體呢?

我自己從網上查了一下,很多關於cookie和session認證的,能不能給我講講

用戶認證呀,可以呀

這樣我下次再去面試,有可能會遇到這樣的問題

原來你是想為面試做準備呀,看來公司收不住你的心了

程序员过关斩将--互联网人必备知识cookie和session认证

用戶認證

在互聯網發展初期,Web基本上只是內容的瀏覽而已,服務器不需要記住每個瀏覽請求的狀態,換句話說,服務器不需要有任何的狀態信息,每次客戶端的請求都是新的請求,這也是http無狀態一個很明顯的表現。隨著互聯網大潮的到來,尤其是像在線購物等這種和用戶關係密切的系統的大量興起,系統需要辨識出用戶,以便進行各種業務操作,這種需求給Http無狀態這種特性一個強烈的衝擊,所以最終的解決方案就是客戶端請求的時候攜帶著一種標識,這種標識每個用戶不同,這樣服務端就可以根據這個標識區分出不同的客戶端用戶了,這也就誕生了用戶認證這個概念。

由於http協議是無狀態的,所以基於http協議進行的認證,都需要依賴客戶端上傳的某種標識

所謂身份認證,就是判斷一個用戶是否為合法用戶的處理過程。

以上是百科針對於用戶認證的泛型定義,和認證相關的授權這裡要順便提一下,認證和授權是兩個不同的概念,更是兩個不同的階段,絕大多數帶有認證和授權的系統,在用戶操作流程上都是先進行認證,之後根據認證的結果再進行授權操作,有的初學者容易混淆二者的概念。舉一個很簡答的栗子:一個OA系統,在用戶登錄成功之後,一般左側都會根據當前用戶的不同角色或者權限出現不同操作的菜單樹,其中用戶登錄這個過程就是認證的過程,而左側的菜單樹就是對當前用戶的授權的一個具體表現形式(當然有的系統可能不這樣做,但不代表沒有授權的流程)。

程序员过关斩将--互联网人必备知识cookie和session认证

認證是用來證明一個用戶身份的操作流程,授權是用來給當前用戶賦予權限的操作流程

session認證

通過上一篇文章,相信大家已經明白了session和cookie的關係,如果你還沒看過,我推薦還是看一下吧。

Session:在計算機中,尤其是在網絡應用中,稱為“會話控制”。Session對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的Web頁之間跳轉時,存儲在Session對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程序的 Web頁時,如果該用戶還沒有會話,則Web服務器將自動創建一個Session對象。當會話過期或被放棄後,服務器將終止該會話。

基於session的認證方式,最主要的一個特點就是:服務端存儲著用戶信息,客戶端是通過攜帶一個sessionid的cookie來做session的標識。很多初期項目都喜歡採用session的認證方式,這種方式對於快速開發上線項目極為有利。每個客戶端只需要保存一個cookie,但是服務端卻需要保存成千上萬的用戶session信息,這無疑對服務端造成了很大的壓力,尤其是當做了負載均衡之後,session的命中問題更為可怕。舉個栗子:用戶A登錄系統成功,服務器A下發sessionid,session信息存儲在服務器A上,如果當下次請求到服務器B上的時候,由於服務器B上沒有session信息,所以就造成了未命中的現象,這也是session認證解決方案實施過程面臨的一個問題。有問題就有解決方案,其中一個便是session複製,服務端的每個服務器都存儲每個session的一個副本,這樣請求無論到達哪個服務器,都可以成功取到session信息,但是這樣無疑增大了服務的存儲壓力,而且session在服務器之間的複製延遲,session信息的更新同步、過期同步等操作都令人頭疼。所以這種方案在一定程度上其實並不推薦。

目前業界關於session存儲的方案一般都傾向於集中式存儲,像利用第三方的redis,Memcached把session信息都存儲在同一個地方,所有的服務器都訪問這個地方的數據。這樣就避免了session複製,同步等問題。但是引入了第三方,就意味著增加了一個第三方掛掉的可能性,所以現在都基本採用第三方集群的方案來儘量減小這種可能性,把高可用性做到極致。另外說一點,由於大多數session機制是基於cookie的,在一定程度上對於瀏覽器比較友好,但是對於很多移動端應用其實並不是太友好。

程序员过关斩将--互联网人必备知识cookie和session认证程序员过关斩将--互联网人必备知识cookie和session认证

由於session的認證信息保存在服務端,數據量到達一定程度對服務器有一定的壓力,即使是採用第三方的存儲(比如redis)可以緩解這種問題,但是服務器和第三方存儲的IO操作所花費的時間有的時候也是很大的。在這種情況下,有的系統放棄了session的認證方式,而直接採用的最直接的cookie認證方式。

和session認證不同,用戶的認證信息完全存儲在cookie中,換句話說用戶的認證信息存儲在客戶端(這也是為什麼不推薦在cookie認證中存放敏感信息)。cookie認證這種方式的優勢就在於服務端沒有了session存儲的壓力,每次識別用戶都只需要解析cookie的內容即可(解析cookie其實也需要花費時間),相比較第三方存儲session的方式,減少了一次網絡IO操作,在一定程度上提高了請求的響應速度,而且由於服務端處於無狀態的形式,所以可以很方便的橫向擴展。

基於cookie的認證方式也有很多缺點:

1. cookie是存儲在客戶端的,所以在一定程度上增加了可以偽造的幾率,安全性上稍微弱一點。

2. 由於cookie在瀏覽中有跨域的阻攔,所以在有跨域需求的時候,需要服務器做相應的配置。

3. cookie是有長度限制的,所以不宜存儲過長的信息。

4. 用戶的客戶端可能會禁用cookie,這個時候可以依靠url傳值來解決這個問題。

5. 服務端想要操作cookie認證信息的失效,比較困難,不像session認證那樣方便。

其實我司現在老的系統都是利用的cookie驗證方式,只不過cookie信息的加密算法很好,而且再加上全站https的策略,在一定程度上安全性還是可以的(如果讓我重構一次認證系統,我不會選擇cookie認證)。

寫在最後

無論是基於session的還是基於cookie的認證方式,都需要客戶端上傳標識,都需要服務端下發這個標識,並且對這個標識進行加密。雖然加密,但是不法之人一旦拿到這個標識還是可以進行一系列非法操作,所以這個標識裡邊最好能加上來源IP和過期時間這些屬性,再配置上https,可以更加有效的保護整個認證流程和數據。也許還有更好的認證方式,敬請期待!!


分享到:


相關文章: