加勒比HEZYO黑人专区-久久精品国产99国产精品亚洲-精品国产18久久久久久-久久人妻少妇嫩草AV

歡迎光臨 織晶網(wǎng)絡(luò)官網(wǎng)!

  • 服務(wù)支持
  • 020-39182790
服務(wù)支持您現(xiàn)在的位置:首頁 > 服務(wù)支持

HTTP Session 的工作原理以及幾個(gè)思維擴(kuò)展

作者:織晶客服部   發(fā)布于:2017/7/10 10:08:41  點(diǎn)擊量:  來源:織晶網(wǎng)絡(luò)

大家都知道,HTTP 協(xié)議本身是無狀態(tài)的,Session 的出現(xiàn)解決了這個(gè)問題,也被大多數(shù) Web 端采用。 但它背后的實(shí)現(xiàn)原理你是否有興趣了解呢,以及在它基礎(chǔ)上的思維發(fā)散,和你聊聊。

無狀態(tài)的 HTTP

大家都知道,我們目前使用的互聯(lián)網(wǎng)應(yīng)用層協(xié)議基本上都是基于 HTTP 和 HTTPS 的,它們的本身是無狀態(tài)的, 只負(fù)責(zé)請求和響應(yīng)。 我告訴服務(wù)器我需要什么,服務(wù)器返回給我相應(yīng)的資源。 如果沒有額外處理的話, 服務(wù)器是不知道你是誰,更無法根據(jù)你是誰給你展現(xiàn)和你相關(guān)的內(nèi)容了。

HTTP 協(xié)議一開始被設(shè)計(jì)成這樣還是有一些歷史原因的,當(dāng)時(shí)的互聯(lián)網(wǎng)多用于學(xué)術(shù)交流,只用于文章信息的展現(xiàn)之類的事情,遠(yuǎn)沒有現(xiàn)在這么豐富多彩。所以在當(dāng)時(shí)的背景下 HTTP 協(xié)議被設(shè)計(jì)成這樣其實(shí)也是很符合它的場景的。

但隨著互聯(lián)網(wǎng)應(yīng)用越來越廣泛,應(yīng)用的形式也變得越來越多,我們的 Web 應(yīng)用不只限于提供簡單的信息展現(xiàn)了,還需要用戶能夠登錄,可以在論壇發(fā)帖子,在購物網(wǎng)站買東西等等。 這就需要 HTTP 協(xié)議能夠記錄用戶的狀態(tài)。也就是我們現(xiàn)在熟悉的 Session 由來。

Session 如何實(shí)現(xiàn)

大多數(shù) Web 框架都提供了操作 Session 的 API。 如果你有 Web 端開發(fā)的經(jīng)驗(yàn),那么你對這樣的代碼應(yīng)該不會(huì)陌生:

 session["name"] = "xxx" 

我們給 session 對象設(shè)置一個(gè)值,比如用戶登錄成功后,給他設(shè)置一個(gè)用戶名,這樣我們這個(gè)用戶的狀態(tài)就保存下來了。 并且后續(xù)的請求中,這個(gè)狀態(tài)都可以讀取到。這一切就這么自動(dòng)的發(fā)生了,并且習(xí)以為常。那么這一行代碼背后發(fā)生了什么呢? 就是下面幾個(gè)步驟。

生成 Session ID

關(guān)于 Session 的工作原理, 其實(shí)還是值得我們了解一下的。 我們調(diào)用上面這行代碼后,我們使用的 Web 框架首先會(huì)給當(dāng)前請求創(chuàng)建一個(gè) Session ID。 這個(gè) Session ID 是通過一系列算法生成的一個(gè)唯一字符串。 這也是一個(gè) Web 框架(PHP, Ruby on Rails, ExpressJS 等)提供的基礎(chǔ)能力,每個(gè)框架生成 Sesssion ID 的具體實(shí)現(xiàn)算法可能有所差別,但整體流程都是一樣的。

建立服務(wù)端 Session 存儲結(jié)構(gòu)

這個(gè)新生成的 Session ID 用于標(biāo)識這次發(fā)起請求的用戶,并存儲到服務(wù)器的某個(gè)區(qū)域中(默認(rèn)情況下會(huì)在內(nèi)存中)。 這個(gè) Session ID 同樣也是本地存儲的一個(gè) key,比如我們上面代碼中設(shè)置了 name 屬性,就相當(dāng)于在這個(gè) key 中設(shè)置了對應(yīng)的屬性。 

把 Session ID 返回給用戶瀏覽器

還繼續(xù)我們剛才的流程,生成完 Session ID 并建立好本地存儲結(jié)構(gòu)后, 服務(wù)端會(huì)在返回給用戶的 HTTP 響應(yīng)消息中帶上這個(gè) Session ID:


如上圖, 通過 Response Header 的 set-cookie 帶上,這樣截圖使用的是基于 Express 的 NodeJS 服務(wù)端框架, 這里面的 connect.sid=xxx 就是服務(wù)端給這個(gè)用戶生成的 Session ID。

這樣,用戶的瀏覽器得到這個(gè) Cookie 后,再下一次請求同一個(gè)網(wǎng)站的時(shí)候就會(huì)在請求中帶上這個(gè) Cookie。

如果你對 Cookie 的細(xì)節(jié)不熟悉的話,不用多想,你可以理解成這樣 — 你用的所有瀏覽器都會(huì)有這個(gè)邏輯,收到 set-cookie 響應(yīng)頭后,就會(huì)把里面的內(nèi)容保存下來,下一次再訪問同樣的站點(diǎn)時(shí)候,就會(huì)把之前保存的 cookie 再重新發(fā)送回去。當(dāng)然,關(guān)于 Cookie 的細(xì)節(jié)還有很多知識,不過理解我的這個(gè)簡單解釋就足夠了,感興趣的話可以再深入研究。

客戶端發(fā)送 Session ID

就會(huì)像我們剛說的,瀏覽器下一次再請求這個(gè)網(wǎng)站時(shí),會(huì)把之前保存的 Session ID 再重新發(fā)給服務(wù)端。 這時(shí)候服務(wù)端就會(huì)用這個(gè) Session ID 和它之前建立的存儲結(jié)構(gòu)中進(jìn)行匹配,如果這個(gè) Session ID 是之前合法創(chuàng)建的,那么就可以從服務(wù)端存儲中得到用戶之前的狀態(tài)了,比如登錄用戶名之類的。

假設(shè)上面是我們服務(wù)端建立的本地 Session 數(shù)據(jù)存儲,如果 Session ID 正確匹配,就能找到對應(yīng)這個(gè)用戶的 name 屬性了。

整體步驟

上面給大家介紹的就是 Session 整體的工作過程。 大概分為這幾個(gè)步驟:

瀏覽器第一次請求網(wǎng)站, 服務(wù)端生成 Session ID。
把生成的 Session ID 保存到服務(wù)端存儲中。
把生成的 Session ID 返回給瀏覽器,通過 set-cookie。
瀏覽器收到 Session ID, 在下一次發(fā)送請求時(shí)就會(huì)帶上這個(gè) Session ID。
服務(wù)端收到瀏覽器發(fā)來的 Session ID,從 Session 存儲中找到用戶狀態(tài)數(shù)據(jù),會(huì)話建立。
此后的請求都會(huì)交換這個(gè) Session ID,進(jìn)行有狀態(tài)的會(huì)話。

擴(kuò)展知識

看完這一套流程后,是不是對我們開始的那一行代碼背后發(fā)生的事情了解的更通透了呢。還有幾個(gè)值得討論的地方也和大家聊聊。

1. Session ID

首先就是 Session ID,如果你理解了前面的介紹后,就會(huì)得到一個(gè)知識,在整個(gè)會(huì)話過程中,最重要的就是 Session ID。一個(gè)相對成熟的 Web 應(yīng)用,往往會(huì)同時(shí)處理成百上千,甚至更大量的用戶同時(shí)在線。 這就對 Session ID 的創(chuàng)建有一個(gè)非常重要的要求,那就是在保證生成性能的同時(shí),不能重復(fù)!

可以想象,如果你的 Web 框架在生成 Session ID 的時(shí)候重復(fù)了,會(huì)發(fā)生什么事情 — 用戶會(huì)誤登錄進(jìn)別人的賬號, 這個(gè)后果還是非常嚴(yán)重的。 好在現(xiàn)在成熟的 Web 框架都考慮到了這個(gè)問題,你知識框架的使用者,所以你不必過于擔(dān)心。但了解背后的這個(gè)原理以及思維方式還是有助于你寫出更安全的程序的。

2. Session 數(shù)據(jù)存儲

另外一個(gè)要聊聊的就是 Session 數(shù)據(jù)的存儲。 通常情況下,如果你不明確的設(shè)置, 大多數(shù) Web 框架會(huì)把 Session 數(shù)據(jù)存放到內(nèi)存中。如果你的 Web 應(yīng)用用戶量不大的話,這也不成問題。 但如果你的用戶數(shù)比較大的話,就可能發(fā)生一個(gè)事情 — 內(nèi)存不夠用了。

這很正常,內(nèi)存容量是非常寶貴的,假設(shè)每個(gè)用戶的 Session 數(shù)據(jù)是 100K, 1萬個(gè)用戶就會(huì)大概占用 1G 的存儲空間,如果你的 Session 數(shù)據(jù)清理機(jī)制也恰巧比較慢的話,內(nèi)存非常容易被占滿。

這就需要你在設(shè)計(jì)比較大并發(fā)量的站點(diǎn)時(shí),要考慮 Session 的存儲方式,比如把它們保存到硬盤文件系統(tǒng)中,或者數(shù)據(jù)庫中。 所以你在開發(fā)一個(gè) Web 應(yīng)用的時(shí)候,如果你的用戶量很大,你需要有這個(gè)意識。

另外 Session 放到內(nèi)存中還有一個(gè)弊端,如果你的 Web 服務(wù)器發(fā)生重啟,那么所有的 Session 狀態(tài)都會(huì)被情況,會(huì)在一定程度上影響用戶體驗(yàn)。

3. 傳輸安全

最后再聊聊傳輸安全,有一種叫做 Session ID 劫持的,假如 Session ID 是基于 HTTP 協(xié)議傳輸?shù)模驗(yàn)槭敲魑膫鬏敚敲此涂赡鼙恢虚g的路由器劫持。 攻擊者得到 Session ID 后,把它帶到自己的請求中,就能夠進(jìn)入你的賬戶。

所以一些 Web 框架還提供了 Session 的一些安全保護(hù),比如間隔時(shí)間內(nèi)動(dòng)態(tài)刷新 Session ID,加上 Token 等。但這些也無法完全保證不被中間人看到。 其實(shí)從這個(gè)角度也間接體現(xiàn)了為什么 HTTPS 這么重要。

總結(jié)

這次跟大家聊了一下 HTTP Session 的原理和整個(gè)工作過程。 透過對它的了解,不僅是對細(xì)節(jié)的掌握,更重要的是這些知識能夠幫助我們理清對技術(shù)整體的思維方式。 包括我們最后說的 Session ID 生成機(jī)制。為什么把 Session 放到內(nèi)存中會(huì)有問題,這樣才會(huì)理解框架為什么要提供硬盤和數(shù)據(jù)庫之類的其他 Session 存儲方式。無論你使用什么框架,什么語言,這些原理性的東西都是不變的。了解的多了,你也就越來越不用焦慮學(xué)哪種技術(shù)有前途這個(gè)問題了。




上一篇:企業(yè)網(wǎng)站制作中要體現(xiàn)出企業(yè)自己的特征

下一篇:移動(dòng)網(wǎng)站在百度搜索優(yōu)化上的一些明確建議