从淘宝首页登录说起
這是 Jerry 2021 年的第 50 篇文章,也是汪子熙公眾號總共第 327 篇原創文章。
今天文章提到的場景,理論上本公眾號每一位粉絲,都可以在自己的電腦上進行操作。因為涉及到的應用,幾乎每一個人日常生活中都會使用到——淘寶網。
Jerry 負責的是 SAP Commerce Cloud 前臺開發,為何要寫和淘寶網相關的文章?
上個周日即7月25日凌晨兩點半,Jerry 所在的 Spartacus 開發團隊,收到了一個客戶 escalation.
這個客戶 incident 和會話管理 (Session Management) 相關,因此 Jerry 一邊和同事處理問題,一邊不禁聯想起,作為另一款國內外數一數二的電商網站,淘寶網是如何處理類似問題的?
在電腦端訪問淘寶網,輸入淘寶用戶名和密碼,點擊登錄:
會觀察到一個 HTTP Post 請求,login,發送往后臺服務器:
https://login.taobao.com/newlogin/login.do?appName=taobao&fromSite=0
該請求的 Form Data 中包含 loginId 和 password2 兩個字段,分別維護了用戶輸入的淘寶用戶名的明文,以及淘寶密碼進行 RSA 加密后的值。
下面介紹如何自行找到淘寶網前端將用戶輸入的登錄密碼進行 RSA 加密的準確位置。
在 Chrome 開發者工具里找到 login 請求,在 Initiator 面板里找到發起該請求的調用棧。稍有經驗的前端開發人員,從 onClick 和 t.loginSubmit 就能推斷出,用戶名和密碼的輸入框,實現在一個 Form 表單里,點擊登錄按鈕后,觸發表單的 Submit.
打開上圖找到的 index.js 文件:
https://x.alicdn.com/vip/havana-nlogin/0.5.61/index.js
直接搜索關鍵字 password2,很快就能找到 RSA 加密的代碼位置:
設置斷點后,運行時點擊登錄按鈕,斷點觸發,可以進入 rsaPassword 函數,查看 RSA 加密算法的明細。
這個 index.js 里還能發現一些有趣的東西。比如提供了 rsaPassword 方法的模塊內部,還維護了一個支持的國家列表,countryList,里面有 168 個國家和地區:
但是在瀏覽器端打開淘寶網,國家和地區的下拉列表里,只能看到十余條記錄。這應該是前臺某處根據某種邏輯做了過濾:
此外,我們在淘寶網首頁右邊區域,能看到快速充值話費的面板,如下圖綠色高亮區域所示:
該頁面的 HTML 源代碼,并不是靜態編寫于首頁的 HTML 文件中,而是通過一個叫做 bianming-phone("便民"的拼音加上"手機"的英文單詞 phone,這混搭風格…) 的 HTTP 請求,從后臺讀取到前臺,然后再注入到前臺頁面中:
同理,還有這個旅行視圖片段(相當于 SAP UI5 里的 View Fragment):
讀取該視圖片段的 HTTP 請求:bianming-trip
看到這里,Jerry 不由得聯想起 SAP Commerce Cloud 前臺的 CMS 驅動設計,二者都是從電商頁面連接的后臺系統讀取部分頁面配置信息,可謂異曲同工。
SAP S/4HANA 的 UI 風格是 Fiori UX,實現的前端框架是 SAP UI5;SAP Commerce Cloud UI 實現的前端框架是 Angular;
help.sap.com 采用 AngulaJS 實現,www.sap.com 使用的是 React.詳情參考 Jerry 的文章:SAP官方幫助網站,help.sap.com 背后那些事兒。
而淘寶網首頁,采用的是阿里自研的前端框架,Kissy:
我們在淘寶網首頁看到琳瑯滿目的商品圖片,都是被 Kissy 驅動,通過向 CDN 服務器發起的數據請求而被加載的:
在這些頁面片段的源代碼里還看到一些有意思的內容,比如這種“上線請刪除”的注釋。我現在瀏覽的就是上線后的代碼呀,咋還能夠看到這些注釋 😃
還有這種給 window 全局對象添加 flag 屬性,賦值為 5 的做法。 作為同行,我非常能理解這種 workaround 😃
想起有一段在國外程序員界很流行的注釋,翻譯成中文大意是:
// 下面這段代碼不要動,因為只有我和上帝,知道這段代碼在干啥
// 現在,只有上帝知道這段代碼在干啥
我們在淘寶網上購物時,選擇好了自己心儀的商品,加入購物車之后,當然不希望點擊結帳之后,忽然彈出要求重新登錄的界面,這豈不是令人掃興。另外,當我們不小心誤操作,點擊了瀏覽器刷新按鈕,我們期望頁面刷新后,仍然處于登錄狀態,之前添加到購物車里的商品不會丟失。這些都屬于用戶會話管理的范疇。
淘寶網頁面的用戶會話管理,是通過客戶端 Cookie 和服務器端維護的用戶會話對象來實現的。
用戶成功登錄淘寶網之后,服務器創建對應的 Session 對象,返回給 login HTTP 請求的響應頭部,包含了很多 set-cookie 字段:
瀏覽器解析這些響應,將服務器頒發的 Cookie 設置到本地。下一次用戶操作淘寶網,觸發新的發向服務器端的請求時,瀏覽器會自動將這些 Cookie 字段設置到請求頭部。服務器接收到這些 Cookie 字段,就能在內存中定位到之前該用戶登錄后對應創建的 Session 對象,從而能夠識別出該用戶。
這些 Cookie 在 Chrome 開發者工具里也能查看。
(1) Cookie 的 Expires 字段存放的是過期時間,當 Expires 為 Session 時,意為該 Cookie 只在當前會話內有效,瀏覽器關閉則 Cookie 自動刪除。
(2) 帶有 Http Only 的 Cookie,無法被客戶端 JavaScript 代碼讀取,提高了安全性,避免了 Cookie 通過 XSS 攻擊被竊取的可能。
(3) Secure 為 true 的 Cookie,無法通過 HTTP 協議傳輸到服務器,只能通過 HTTPS 發送。
淘寶服務器頒發的 Cookie 里,字段 lid 存儲的是淘寶用戶名經過 URL encode 之后的值,dnk 存放的是淘寶用戶名的 Unicode:
有了本文的基礎,下一篇文章 Jerry 會介紹 SAP Commerce Cloud UI 的用戶會話管理,感謝閱讀。
更多Jerry的原創文章,盡在:“汪子熙”:
總結
- 上一篇: SAP Spartacus OCC 请求
- 下一篇: OAuth 2.0 协议学习笔记