來源:互聯(lián)網(wǎng) 閱讀:-
當(dāng)前移動app最常見的保持登錄的方案就是:持續(xù)刷新的JWT(json web token)方案。
即用戶登錄后,客戶端獲得JWT,此后不斷刷新或是過期后刷新token。
這個方案使用得十分廣泛,幾乎成了事實標(biāo)準。但并不安全,有以下幾個問題:
1,JWT 密鑰管理問題
JWT 的安全的基石是保證秘鑰(secret key)的安全,因為一旦秘鑰泄露,擁有秘鑰的人可以偽造所有用戶。這給管理帶來了麻煩,我們還要完全信任管理人員,管理人員變動就要修改秘鑰,而修改秘鑰又會打斷用戶的登錄狀態(tài)。也許有人會說,這不是問題,這個和數(shù)據(jù)庫賬號密碼管理一樣啊,這個還有些不同,生產(chǎn)環(huán)境的數(shù)據(jù)庫賬號密碼通常會有登錄IP限制。
2,JWT 無法注銷的問題
當(dāng)用戶修改密碼后,通常需要注銷之前頒發(fā)的token,為了實現(xiàn)這個功能需要引入token的集中儲存和檢查,這破壞了JWT分布式的優(yōu)點。
3,JWT 的刷新機制有問題。
為了安全,很多人都知道token長期保持不變不安全,通常會采取刷新token的機制。當(dāng)是當(dāng)下,很多刷新機制是為了刷新而刷新,常見的token刷新機制是:到期后刷新,或是提前刷新,或者定時刷新。如果token被盜,黑客和合法用戶都可以通過刷新來獲取新的token,這并沒帶來實際的安全提升。
1,針對JWT秘鑰管理問題
這里給出的方案就是不使用JWT, 采用一個類似session 的機制,使用一個隨機值(uuid)做token, 用戶數(shù)據(jù)在后臺集中的redis存儲和查詢。暫且稱之為UUID Redis Token.
JWT的最大有點就是自身可存儲用戶數(shù)據(jù),不用到集中的存儲點查詢,便于分布式應(yīng)用,這個特點導(dǎo)致了已發(fā)布的JWT無法撤銷?,F(xiàn)實中,很多使用JWT的公司并不是單純的在jwt里取用戶數(shù)據(jù),依舊在集中的服務(wù)器取數(shù)據(jù)。還有,對于像圖片,視頻等需要用戶登錄的檢查,通常把token放到url 里,而JWT顯得數(shù)據(jù)過大。
使用redis在后端保存用戶信息有良好的擴展性,足夠應(yīng)滿足大型網(wǎng)站的需求。
這個的uuid 并不要求按標(biāo)準格式,只需不重復(fù)即可,對于PHP 很容易生成:
$token = bin2hex(random_bytes(20));
不要嫌這一行代碼過于簡單,對于地球上的公司,這已經(jīng)足夠安全了。
講到這里,這個機制和傳統(tǒng)的session 機制是類似的,uuid 相當(dāng)于session-id,不同的地方是傳統(tǒng)session客戶端一定時間(通常為20分鐘)不活躍就自動退出,我們需要做些改進,滿足手機APP長期登陸的需求。
2,改進方案(UUID Redis Token)的特點
為了表述方便,以下假設(shè)手機APP要求90天內(nèi)保持登陸,token超過2小時就刷新
此方案,多數(shù)情況下只是對redis的讀寫操作,性能極高,在刷新token時,需要用到redis或MySQL的鎖機制防止并發(fā)刷新,確保同一客戶端一次刷新只有一個請求刷到新的token,由于刷新token操作間隔的時間較長,不是高頻操作,對性能也影響不大,配合redis集群,足夠應(yīng)對海量用戶。
對于對安全有極致要求的公司,這里還有進一步的安全措施。
1,對用戶token做哈希運算
對UUID,也就是用戶的token,作一次SHA256哈希運算,以此哈希值作為后臺redis的key值,這樣就算是服務(wù)器的超級管理員,也無法查看用戶的token,有的同學(xué)可能擔(dān)心做一次格外的哈希運算是否會加大服務(wù)器的負荷,這樣的多擔(dān)心是多余,一次SHA256哈希運算對服務(wù)器來說微乎其微,可以忽略不計。
如果覺得這還不安全,我們還可以以UUID為密鑰,對會話數(shù)據(jù),也就是redis的value值做AES加密(AES算法的格外負荷極低),這樣就徹底安全了,就算是公司老板,超級管理員也看不到。
2,用戶token被盜檢查
增加token防盜檢查。如果Token被黑客獲取,根據(jù)我們的設(shè)計,黑客和合法用戶都需每兩個小時來刷新一次,我們可以識別這樣的異常,提升安全性。
這里以身份證換證類比講述,身份證的以舊換新,一個舊證只能換一個新證,我們可以對已經(jīng)換過的舊證集中登記,如果發(fā)現(xiàn)一個證件兩次來換新證,就視為異常。
同理,用戶token的刷新操作,可以看作一次以舊換新,一個舊token只能換一個新的token,我們在服務(wù)器集中記錄最近換過的舊token,如果發(fā)現(xiàn)同一token,試圖兩次來換新的token,則視為異常,注銷該用戶,要求用戶用密碼再次登錄。以上這些邏輯只需要在刷新token的時候處理,所以對服務(wù)器的格外負荷不大。
如果大家覺得以上處理機制過于復(fù)雜。
對于很多中小企業(yè),安全要求不高,直接用session機制,會話時長直接設(shè)為90天,加上https防監(jiān)聽,就夠了,這個也比JWT把千萬用戶的安全寄希望于一個密鑰的機制安全。
推薦閱讀:充電寶品牌排行