小白必讀:閒話HTTP短鏈接中的Session和Token

本文引用了劉欣的文章,感謝原做者的分享。php

一、引言

Http協議在現今主流的IM系統中擁有無可替代的重要性(在IM系統中用HTTP發起的鏈接被你們簡稱爲http短鏈接),但Http做爲傳統互聯網信息交換技術,一些典型的概念好比:Session、Token,對於新手程序員來講很陌生。html

不少文章動輒長篇大論、高屋建瓴地從底層協議再到上層分佈式應用式的講解,根本不適合傻白甜程序員,本文的寫做目的是以最白話地方式,通俗易懂的爲你講清HTTP協議中的Session和Token等概念,但願讀徹底文,您仍能滿懷信心,繼續義無反顧地跳入程序員這個職業深坑 ^_^。更深刻的技術細節,請閱讀《IM開發基礎知識補課(四):正確理解HTTP短鏈接中的Cookie、Session和Token》。程序員

學習交流:算法

- 即時通信開發交流3羣:185926912[推薦]編程

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM瀏覽器

(本文同步發佈於:http://www.52im.net/thread-1686-1-1.html)安全

二、互聯網源起

1990年12月25日,羅伯特·卡里奧在CERN(即位於日內瓦的歐洲原子核研究會)和蒂姆·伯納斯·李一塊兒成功經過Internet實現了HTTP代理與服務器的第一次通信(有關HTTP的詳細介紹,請見《網絡編程懶人入門(六):深刻淺出,全面理解HTTP協議》)。蒂姆·伯納斯·李(Tim Berners-Lee)爵士做爲萬維網(World Wide Web,簡稱WWW或互聯網)的發明者,被尊稱爲互聯網之父。蒂姆·伯納斯·李創建的第一個網站(也是世界上第一個網站)是http://info. cern. ch/,它於1991年8月6日上網(即北京時間8月7日)。服務器

 
▲ 互聯網之父——伯納斯·李(Tim Berners-Lee)

1955年6月8日,伯納斯·李出生於英格蘭倫敦西南部。他的父母都參與了世界上第一臺商業電腦,曼切斯特1型(Manchester Mark I)的建造。2017年,他因「發明萬維網、第一個瀏覽器和使萬維網得以擴展的基本協議和算法」而得到2016年度的圖靈獎,同時還有100萬美圓獎金(該獎金由谷歌公司提供)。微信

 
▲ 圖靈獎獎盃實物

在此前的倫敦2012奧運會開幕式上,開幕式總導演丹尼·博伊爾特別爲表揚蒂姆·伯納斯·李爵士的功績,設計了激動人心的一幕:蒂姆·伯納斯·李爵士在「倫敦碗」場館中央用電腦鍵盤敲出了一句話:This Is For Everyone(爲了每個人)。網絡

媒體評述:「若是蒂姆·伯納斯-李爵士爲互聯網申請專利,他將是世界最富有的萬億富豪」。可是,蒂姆·伯納斯-李爵士將他的發明無償貢獻給全人類。

 
▲ 蒂姆·伯納斯·李爵士參與了倫敦奧運2012開幕式的表演
 
▲ 蒂姆·伯納斯·李爵士在「倫敦碗」場館中央用鍵盤敲下的「This is For Everyone」
 
▲ 如今的「互聯網」已無比龐大

(本圖來自:《技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)》一文)

三、相關文章

IM開發基礎知識補課(四):正確理解HTTP短鏈接中的Cookie、Session和Token

IM開發基礎知識補課(一):正確理解前置HTTP SSO單點登錄接口的原理

移動端IM登陸時拉取數據如何做到省流量?

通俗易懂:基於集羣的移動端IM接入層負載均衡方案分享

淺談移動端IM的多點登錄和消息漫遊原理

談談移動端 IM 開發中登陸請求的優化

好了,咱們開始正文的閱讀。

四、美好的舊時光

我常常想象並懷念三十年前那原始而美好的互聯網舊時光, 工做很輕鬆, 生活很清閒。

上班的時候偶爾有些HTTP的請求發到我這裏, 我簡單的看一下, 取出相對應的html文檔,圖片,發回去就能夠了, 而後就能夠繼續喝茶聊天。

 
▲ 早期IE瀏覽器界面

個人創造者們對我很好, 他們制定的一個簡單HTTP協議, 就是請求加響應,  尤爲是我不用記住是誰剛剛發了HTTP請求,   每一個請求對我來講都是全新的!

郵件服務器很羨慕我, 他說:老弟,你的生活太愜意了,  哪像我, 每次有人從客戶端訪問郵箱, 我都得專門給他創建一個會話, 來處理他發的消息, 你倒好, 徹底不用管理會話。

這是由應用的特性決定的, 若是郵件服務器無論理會話, 那多我的之間的郵件消息就會徹底混到一塊兒了, 亂做一團了。

而30年前的Web 基本上就是文檔的瀏覽而已, 既然是瀏覽,我做爲一個服務器, 爲何要記住誰在一段時間裏都瀏覽了什麼文檔呢?

五、是時候該Session出場了

可是好日子沒持續多久, 很快你們就不知足於靜態的Html 文檔了, 交互式的Web應用開始興起, 尤爲是論壇, 在線購物等網站。

我立刻就遇到了和郵件服務器同樣的問題, 那就是必須管理會話,必須記住哪些人登陸系統,  哪些人往本身的購物車中放了商品,  也就是說我必須把每一個人區分開。

這對我來講是個不小的挑戰, 因爲HTTP協議的無狀態特性, 我必須加點小手段,才能完成會話管理。

我想出的辦法就是給你們發一個會話標識(session id), 說白了就是一個隨機的字符串,每一個人收到的都不同,  每次你們向我發起HTTP請求的時候,把這個字符串給一併捎過來, 這樣我就能區分開誰是誰了。

六、沉重的負擔

你們都很高興, 但是我就不爽了。

每一個人只須要保存本身的session id,而我須要保存全部人的session id !  若是訪問個人人多了, 就得由成千上萬,甚至幾十萬個。

這對我來講是一個巨大的開銷 , 嚴重的限制了個人擴展能力, 好比說我用兩個機器組成了一個集羣, 小F經過機器A登陸了系統,  那session id會保存在機器A上,  假設小F的下一次請求被轉發到機器B怎麼辦?  機器B可沒有小F的 session id啊。

有時候我會採用一點小伎倆: session sticky , 就是讓小F的請求一直粘連在機器A上, 可是這也無論用, 要是機器A掛掉了, 還得轉到機器B去。

那我只好作session 的複製了, 把session id  在兩個機器之間搬來搬去, 快累死了。

 

後來有個叫Memcached的給我支了招: 把session id 集中存儲到一個地方, 全部的機器都來訪問這個地方的數據, 這樣一來,就不用複製了, 可是增長了單點失敗的可能性, 要是那個負責session 的機器掛了,  全部人都得從新登陸一遍, 估計得被人罵死。

 

我也嘗試把這個單點的機器也搞出集羣,增長可靠性, 但無論如何, 這小小的session 對我來講是一個沉重的負擔。

七、時間換空間:Token是個不錯的方案

這幾天的晚上我一直在思考, 我爲何要保存這可惡的session呢, 只讓每一個客戶端去保存該多好?

但是若是我不保存這些session id ,  我怎麼驗證客戶端發給個人session id 的確是我生成的呢?  若是我不去驗證,我都不知道他們是否是合法登陸的用戶, 那些不懷好意的傢伙們就能夠僞造session id , 隨心所欲了。

嗯,對了,關鍵點就是驗證 !

好比說, 小F已經登陸了系統, 我給他發一個令牌(token), 裏邊包含了小F的 user id, 下一次小F 再次經過Http 請求訪問個人時候, 把這個token 經過Http header 帶過來不就能夠了。

不過這和session id沒有本質區別啊, 任何人均可以能夠僞造,  因此我得想點兒辦法, 讓別人僞造不了。

那就對數據作一個簽名吧, 好比說我用HMAC-SHA256 算法,加上一個只有我才知道的密鑰,  對數據作一個簽名, 把這個簽名和數據一塊兒做爲token ,   因爲密鑰別人不知道, 就沒法僞造token了。

 

這個token 我不保存,  當小F把這個token 給我發過來的時候,我再用一樣的HMAC-SHA256 算法和一樣的密鑰,對數據再計算一次簽名, 和token 中的簽名作個比較, 若是相同, 我就知道小F已經登陸過了,而且能夠直接取到小F的user id ,  若是不相同, 數據部分確定被人篡改過, 我就告訴發送者: 對不起,沒有認證。

 

Token 中的數據是明文保存的(雖然我會用Base64作下編碼, 但那不是加密), 仍是能夠被別人看到的, 因此我不能在其中保存像密碼這樣的敏感信息。

固然, 若是一我的的token 被別人偷走了, 那我也沒辦法, 我也會認爲小偷就是合法用戶, 這其實和一我的的session id 被別人偷走是同樣的。

這樣一來, 我就不保存session id 了, 我只是生成token , 而後驗證token ,  我用個人CPU計算時間獲取了個人session 存儲空間 !

解除了session id這個負擔,  能夠說是無事一身輕, 個人機器集羣如今能夠輕鬆地作水平擴展, 用戶訪問量增大, 直接加機器就行。這種無狀態的感受實在是太好了!

附錄:IM開發綜合性文章

移動端IM開發者必讀(一):通俗易懂,理解移動網絡的「弱」和「慢」

移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結

從客戶端的角度來談談移動端IM的消息可靠性和送達機制

現代移動端網絡短鏈接的優化手段總結:請求速度、弱網適應、安全保障

騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路

小白必讀:閒話HTTP短鏈接中的Session和Token

IM開發基礎知識補課:正確理解前置HTTP SSO單點登錄接口的原理

移動端IM中大規模羣消息的推送如何保證效率、實時性?

移動端IM開發須要面對的技術問題

開發IM是本身設計協議用字節流好仍是字符流好?

請問有人知道語音留言聊天的主流實現方式嗎?

IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞

IM消息送達保證機制實現(二):保證離線消息的可靠投遞

如何保證IM實時消息的「時序性」與「一致性」?

一個低成本確保IM消息時序的方法探討

IM單聊和羣聊中的在線狀態同步應該用「推」仍是「拉」?

IM羣聊消息如此複雜,如何保證不丟不重?

談談移動端 IM 開發中登陸請求的優化

移動端IM登陸時拉取數據如何做到省流量?

淺談移動端IM的多點登錄和消息漫遊原理

徹底自已開發的IM該如何設計「失敗重試」機制?

通俗易懂:基於集羣的移動端IM接入層負載均衡方案分享

微信對網絡影響的技術試驗及分析(論文全文)

即時通信系統的原理、技術和應用(技術論文)

開源IM工程「蘑菇街TeamTalk」的現狀:一場虎頭蛇尾的開源秀

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)

騰訊原創分享(一):如何大幅提高移動網絡下手機QQ的圖片傳輸速度和成功率

騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)

騰訊原創分享(三):如何大幅壓縮移動網絡下APP的流量消耗(下篇)

如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源

基於社交網絡的Yelp是如何實現海量用戶圖片的無損壓縮的?

騰訊技術分享:騰訊是如何大幅下降帶寬和網絡流量的(圖片壓縮篇)

騰訊技術分享:騰訊是如何大幅下降帶寬和網絡流量的(音視頻技術篇)

爲何說即時通信社交APP創業就是一個坑?

>> 更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-1686-1-1.html)

相關文章
相關標籤/搜索