《碼農翻身》之浪潮之巔的Web
《碼農翻身》讀書筆記之浪潮之巔的Web
這是我的後端讀書筆記系列文章的第三篇,選取的是最近剛剛圈粉的知名博主劉欣創作的《碼農翻身》。
本文內容主要根據知名博主劉欣一作《碼農翻身》的內容總結而來,本書的內容風趣幽默,講解計算機理論原理也是十分透徹,由於書中常常以小故事的形式出現,為了方便學習和回顧,我把它們進行了一些改編和整理,便於自己和跟多人閱讀。
本篇文章主要講述的書中的第三章“浪潮之巔的Web”。
本文首發於我的個人部落格:https://h2pl.github.io/
同時發表在csdn技術部落格上:https://blog.csdn.net/a724888
也歡迎來我的GitHub中交流學習:https://github.com/h2pl/
Web的起源
很早以前http還沒有出現,html也尚未問世,人們最多就是傳送一下郵件,用ftp傳遞檔案這些基本的功能。後來為了更好地進行資源共享和展示,出現了html文字,可以在上面展示各種內容。與之一起出現的是瀏覽器,瀏覽器可以解析html文字,渲染出頁面。
只有html文字還不夠,必須要解決通訊和網際網路訪問的需求,於是url用於定位自願,而HTTP協議也應運而生,很好地支援了網際網路資源的訪問。http伺服器也相應產生,比如Apache。
世界開始互聯,www全球資訊網把這些小網連成了大網,實現了世界的互聯。
兩個程式的愛情故事
本地的程式通訊採用的是共享記憶體等機制,速度較快效率也高。作業系統保證通訊的正確性和同步。
而兩臺機器上的程式通訊則必須使用網路傳輸,基於socket的程式通訊也十分常見,客戶端需要完成三次握手,然後進行io請求和接收。
socket會繫結埠號和ip進行服務監聽,但是有的機器安裝防火牆以後禁止了很多埠的訪問,於是我們可以使用應用層協議比如http來繞過防火牆,因為它一般是監聽80埠,且使用url作為endpoint來訪問,不會被防火牆攔截。
web服務的描述方式有多種,除了應用於瀏覽器的html以外。
我們還可以用它來傳輸其他資料,比如進行服務呼叫。
這時候可以採用webservice的wsdl和soap,但是這個協議的資料太臃腫冗餘了,還是用HTTP加json資料格式的方式進行傳輸最為方便高效。
一個故事講完HTTPS
網路上的通訊是明文通訊,每個報文都可能被擷取。
HTTP加密發展歷程:
對稱加密
可以使用加密演算法加密明文,然後傳送金鑰給接收方,讓其使用金鑰進行解密。
但是金鑰會被竊取或者替換,根本不安全。
非對稱加密
上述使用對稱加密的方法不安全,於是我們可以用非對稱加密來保證安全,非對稱加密使用公鑰加密,私鑰解密,公鑰是公開的,丟失也無妨。
兩者結合
上述方法雖好,但是非對稱加密比對稱加密慢百倍,於是可以結合兩種加密方式,非對稱加密傳輸金鑰,然後用這個金鑰進行對稱加密。
中間人劫持
雖然上述方式不錯,但是非對稱加密中的公鑰可能被攻擊者替換,客戶端用被替換的公鑰進行加密,攻擊者就可以獲取報文內容了。
那麼我們需要保證公鑰沒被替換,可以攘服務端到公正中心註冊,證書中心頒發一個證書,包含著可信服務方的公鑰。
數字簽名
雖然證書保證公鑰的可靠,但是證書傳輸過程中仍然可能被篡改,必須保證證書沒有被修改,可以讓認證中心CA對證書中的訊息摘要(一般是一些頭部資訊)進行加密,形成數字簽名,客戶端驗證此簽名解密後的摘要和自己生成的摘要是否一樣,就知道是否有被篡改了。
CA證書
事實上中間人還是可以偽裝成CA來派發假的證書或者公鑰,所以我們必須要知道CA的真實性。其實在作業系統和瀏覽器已經內建了一些CA證書,這些頂層的CA證書可以驗證其他CA證書的真偽,所以有時候瀏覽器才會提示該證書可能不安全,這就是因為內建CA證書不認識這些外來證書。
HTTPS流程
瀏覽器發起https請求
服務端傳送數字證書給客戶端
瀏覽器用預置CA驗證證書,提示風險
瀏覽器得到公鑰,生成隨機數,用公鑰加密該隨機數,發給服務端
服務端用私鑰解密獲得瀏覽器的隨機數,用該隨機數作為金鑰和客戶端進行對稱加密通訊
機房夜話(單點登入sso和cas)
cookie,session與token
多個系統如何實現一個系統登入,其他系統也自動登入呢。
首先想到的是,session用於儲存登入狀態,用cookie儲存sessionid。
我們只要在訪問其他系統的時候也帶上cookie,是不是就能登陸成功呢。
這個方案有兩個問題:
1 cookie不能跨域
2 即使使用二級域名來避免跨域,不同系統中的session互不相干,沒有共享。
共享session
既然上面提到需要共享session,那我們那每個系統都訪問session服務即可,session服務可以用redis來實現。
然而,異構的系統,語言可能不同,共享session的方式可能導致不相容的問題,這也不是最好的方案。
使用token
token與session不同,只是一個特殊字串,不需要儲存在服務端,當使用者登陸成功時服務端加密使用者資訊生成token,返回cookie給客戶端,客戶端儲存cookie。
token裡一般包含使用者資訊和簽名,這部分資料還要進行一次加密。這樣的話服務端通過解密演算法得到使用者資訊和簽名,對使用者資訊再進行一次加密,對比兩個簽名是否相同就可以知道該token是否是真的了。
這個辦法不錯,但是有一個問題,每個系統中的使用者id可能都不同,生成的token也不同,並且每個系統的加密演算法還必須一致,很不靈活。
cas單點登入實現
1 首先我們需要一個註冊中心
2 對於每個系統的登陸請求,都會轉發到這個註冊中心上。
3 在註冊中心登陸成功後,註冊中心建立一個session,並且給瀏覽器一個cookie(這個cookie可以讓瀏覽器下次訪問註冊中心時無須再登陸)。除此之外,還有很重要的一步,就是執行請求轉發,redirect到之前對系統的訪問請求,同時攜帶了一個註冊中心生成的ticket。
4 這個ticket就是客戶端訪問其他系統的鑰匙了。為什麼呢。因為請求到達對方系統時,對方也會轉發該請求到註冊中心上,並且詢問該ticket是否是註冊中心所發,註冊中心說是的,此時對方系統就會為客戶端建立一個session,表示該使用者已經登陸了,當然對方系統也會返回一個cookie給客戶端,下次訪問該系統時不需要再通過註冊中心了。
5 當需要訪問另一個系統B時,我們已不必再次在註冊中心登入了,因為已經有了註冊中心的cookie,直接訪問系統B,B轉發給註冊中心,驗證通過即可。
單點登出:
既然有單點登入,那麼單點登出也是必不可少的,一個使用者從任一系統登出,就要通知註冊中心,刪除session和客戶端的cookie。還要通知各個系統把該使用者相關的session進行刪除。這樣才能真正地實現退出。
從密碼到token,一個有關授權的故事
第三方登入的實現
現在越來越多的app和web應用支援使用第三方渠道登入,比如微信,qq等等,但實際上第三方登入並不會讓app應用真的得到你的使用者密碼。那麼它是怎麼做到的呢。
第三方登入首先是請求app登入,然後跳轉到登入頁面比如qq,然後輸入使用者名稱密碼傳送登陸請求,qq登入服務接收請求並且傳送重定向請求,url中攜帶token字串。
該token字串是使用者登入成功後qq服務提供的身份標識,app通過此token就可以到騰訊伺服器獲取該使用者的qq基本資訊了。
但是由於token加在url中明文傳輸不太安全,可能會被截獲然後冒名登入。
OAuth認證方式
上述方式存在安全隱患,於是我們設想出了不在url中攜帶token,而是先讓qq服務接受登入請求後先返回一個code認證碼放在url中,app應用再通過這個code碼,重新傳送請求到認證伺服器,本次傳送不經過瀏覽器,所以獲得到的token比較安全,並且code認證碼可以設定有效時間,過期後不能使用,同時,code兌換token的請求只能執行成功一次,成功後code碼自動刪除。保證了一次登入的成功,避免重複登入和偽造登入。
後端風雲
為了加快訪問速度和緩解資料庫壓力,採用快取比如Redis,為了克服單機瓶頸,開始從單機部署進化到多機部署。
多機部署需要請求分發,nginx可以做到這一點。
分散式方案:
1 nginx
nginx負責處理靜態請求以及負載均衡,基本是無狀態的,所以高可用只需要用keepalived即可實現主從部署。
2 Tomcat 伺服器
Tomcat伺服器採用叢集就可以實現高可用,但是資料一致性需要額外保證,使用Redis儲存session這類資料就可以保證叢集的高可用。
3 Redis
伺服器訪問Redis叢集需要進行主從部署,使用一致性hash進行分片。也可以使用hash slot也就是hash槽進行分片,Redis cluster就是根據這個方法進行叢集部署的。每個節點都可以提供服務,只不過資料是分散儲存的。
4 Mysql
MySQL可以使用主從複製進行部署,並且讀寫分離。
soa到微服務
soa太笨重了,類似webservice這樣的服務使用wsdl和soap這樣複雜的資料格式。
微服務則一般基於tcp自定義協議進行rpc呼叫,也可以使用http + json的方式傳輸資料,使用restful風格的api。
相關文章
- 產品讀書《浪潮之巔》
- 《碼農翻身》讀後感
- 浪潮之巔,程式設計師如何擁抱新技術?程式設計師
- 《盜賊之海》的「鹹魚」翻身記
- 演算法社會:“碼農”翻身為“編碼精英”帶來的思考?演算法
- 平庸前端碼農之蛻變 — AST前端AST
- 資料浪潮之間的前端工程師前端工程師
- 前端碼農之蛻變 — AST(抽象語法樹)前端AST抽象語法樹
- 《鬼泣-巔峰之戰》7月23日開啟巔峰測試!
- 復旦-華盛頓EMBA:科創的奧E丨從《浪潮之巔》讀懂科技產業的四大定律下篇產業
- Web前端安全之安全編碼原則Web前端
- 首屆“祥雲杯”網路安全大賽火熱報名中,“紫禁之巔,巔峰之戰”等你來
- 《菜農升職記》之 WebsocketWeb
- Web安全之跨站指令碼攻擊(XSS)Web指令碼
- 資訊洩露之web原始碼洩露Web原始碼
- web系列之AjaxWeb
- Web 安全之 XSSWeb
- Cesium之Web WorkersWeb
- Web框架之TornadoWeb框架
- Web 效能之 TCPWebTCP
- 從抄書到開源之巔:章亦春的程式人生
- 005 Web Assembly之測試康威遊戲程式碼Web遊戲
- ctfshow web入門之web259Web
- Flutter Web 之 Hello WorldFlutterWeb
- XML安全之Web ServicesXMLWeb
- Python之Web框架DjangoPythonWeb框架Django
- Web前端之圖表Web前端
- 《菜農升職記》之 Docker網路Docker
- 在發售一個月之後 “褒貶不一”的《永劫無間》翻身了
- 碼農的初心
- idea之設定web工程的TomcatIdeaWebTomcat
- 巔峰對決之後,量子力學“諸神”散落何方?
- 六年碼農生涯的 2019 總結:君子坐而論道,少年起而行之
- 智慧算力站上“世界之巔”,如何開啟冰山下90%的未知世界?
- 屹立於技術之巔的 4 門語言創造者 — Anders Hejlsberg
- 現代農業之智慧農業物聯網系統解決方案
- Web 安全之混合內容Web
- go-zero之web框架GoWeb框架