背景
在賬號體系里恤磷,用戶登錄后拼缝,一般會生成一個加密的token保存在用戶端个扰,每次用戶端和服務(wù)端的交互會帶上它,從而服務(wù)端可以獲取用戶的信息萎津,而不需要每次都帶上用戶的賬號+密碼卸伞。我們稱這個token為用戶登錄態(tài),它其實(shí)是用戶通過密碼(獲取手機(jī)號+驗(yàn)證碼/掃碼等方式)換取的一個通行證锉屈,這個通行證在一定時間內(nèi)荤傲,可以代表當(dāng)前用戶。
需求
-
安全
- 偽造
當(dāng)我們費(fèi)盡心機(jī)的保護(hù)好用戶密碼的時候颈渊,如果用戶的登錄態(tài)可以被人偽造遂黍,我們的工作就會功虧一簣。因?yàn)樗丝梢圆煌ㄟ^密碼就能制造一個通行證俊嗽,如同本來我去辦理護(hù)照是需要帶上我個人身份證和其他資料才能辦理的雾家,現(xiàn)在有個制假證的,不需要你任何證件绍豁,只要知道你的名字芯咧,就可以幫你造一本護(hù)照出來。
因此竹揍,防止被偽造是登錄態(tài)設(shè)計的基本需求敬飒。 - 竊取
很多時候,我們會在一些公關(guān)網(wǎng)絡(luò)上網(wǎng)芬位,如果網(wǎng)站沒有做類似https等加密的傳輸无拗,用戶端和服務(wù)端的請求很容易被截獲,而一般登錄態(tài)會存在cookie中昧碉,很容易被別人竊取英染。同樣的,知道你的登錄態(tài)后被饿,我就可以以你的身份去網(wǎng)站操作了四康。因此,如何防止被竊取的場景锹漱,也是登錄態(tài)設(shè)計的重要安全需求箭养。
- 偽造
失效
登錄態(tài)失效的場景有:過期慕嚷、修改密碼等哥牍。比如用戶修改了密碼毕泌,則之前設(shè)備的登錄態(tài)需要立即失效。用戶體驗(yàn)
性能
如果我們設(shè)計了一個很復(fù)雜的登錄態(tài)嗅辣,黑客很難破解撼泛,但是可能我們也要花上幾秒鐘才能解析出來,也是有問題的澡谭。賬號系統(tǒng)是基礎(chǔ)服務(wù)愿题,業(yè)務(wù)都會基于這些服務(wù)做功能,如果賬號的服務(wù)性能有問題蛙奖,對用戶體驗(yàn)是非常大的挑戰(zhàn)潘酗。互斥
微信只允許一個手機(jī)處于活躍狀態(tài),而京東卻可以用一個賬號在兩個手機(jī)上一起下單雁仲。我們今天討論的是后者的設(shè)計方案仔夺,允許一個賬號同時活躍在兩個手機(jī)上的場景。要實(shí)現(xiàn)微信這樣即時通訊類應(yīng)用需要的互斥性攒砖,還有點(diǎn)不一樣缸兔。
實(shí)現(xiàn)
-
核心數(shù)據(jù)
- TimeStamp:記錄創(chuàng)建登錄態(tài)的時間,用于后續(xù)的過期控制吹艇《杳郏可以精確到毫秒,精確度高受神,但就是無法通過userId來復(fù)現(xiàn)用戶使用的登錄態(tài)抛猖。
- UserPlatform:APP和PC的安全性不一樣,所以可能對于不同平臺的有效期不一樣路克,用這個字段來記錄當(dāng)前平臺樟结,會對后續(xù)的過期等策略有影響。
- UserIP:記錄用戶IP精算,幫助后續(xù)判斷登錄態(tài)的使用場景瓢宦。如,對于pc環(huán)境灰羽,換了IP后驮履,可能該登錄態(tài)就自動失效了。
- RandomX:每個用戶都有這樣的一個值存在服務(wù)器端廉嚼,用戶修改密碼后玫镐,服務(wù)端的值隨機(jī)變化,之前的登錄態(tài)中的RandomX不再匹配怠噪,實(shí)現(xiàn)T除登錄態(tài)的作用恐似。
- 核心數(shù)據(jù)加密
在登錄態(tài)的場景中,加密算法一般采用對稱加密傍念,如DES/AES等矫夷。加密除了輸入加密串葛闷,還需要一個key和iv,可以將key和iv都取一樣的值双藕,也可以采用多組key和iv淑趾,多組的場景就需要在登錄態(tài)中標(biāo)志下。 -
外層數(shù)據(jù)
- 版本號:后續(xù)方便版本升級
- 簽名:為了保證登錄態(tài)不被篡改和快速驗(yàn)證其有效性忧陪,在前面可以加簽名扣泊。算法自選,用常用的hash算法就可以了嘶摊。
- 其他:如果在核心數(shù)據(jù)加密算法中想采用多組Key和IV的場景延蟹,在外層數(shù)據(jù)中需要添加一些其他信息來區(qū)分。當(dāng)然叶堆,這樣拼接出來的字符都是有意義的等孵,防止泄露過多信息,最后可以將整個串再使用類似base64的算法編碼一次蹂空。
總結(jié)
登錄態(tài)的設(shè)計需要兼顧性能和安全性俯萌,本文給到了一種比較常見的設(shè)計方案。
參考
- 《搬運(yùn)工:用戶登錄功能設(shè)計》https://my.oschina.net/EugeneQiu/blog/155974
- AES https://en.wikipedia.org/wiki/AES