文章轉(zhuǎn)自喜歡出發(fā)的csdn博客,附上原文地址:https://blog.csdn.net/weixin_41918841/article/details/82227136#commentsedit
原文:
什么是JWT?
Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開(kāi)放標(biāo)準(zhǔn)((RFC 7519).該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。JWT的聲明一般被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息,該token也可直接被用于認(rèn)證,也可被加密。
基于 Token 的身份驗(yàn)證
基于token的鑒權(quán)機(jī)制類(lèi)似于http協(xié)議也是無(wú)狀態(tài)的,它不需要在服務(wù)端去保留用戶的認(rèn)證信息或者會(huì)話信息。這就意味著基于token認(rèn)證機(jī)制的應(yīng)用不需要去考慮用戶在哪一臺(tái)服務(wù)器登錄了,這就為應(yīng)用的擴(kuò)展提供了便
大概的流程是這樣的:
客戶端使用用戶名跟密碼請(qǐng)求登錄
服務(wù)端收到請(qǐng)求,去驗(yàn)證用戶名與密碼
驗(yàn)證成功后,服務(wù)端會(huì)簽發(fā)一個(gè) Token,再把這個(gè) Token 發(fā)送給客戶端
客戶端收到 Token 以后可以把它存儲(chǔ)起來(lái),比如放在 Cookie 里或者 Local Storage 里
客戶端每次向服務(wù)端請(qǐng)求資源的時(shí)候需要帶著服務(wù)端簽發(fā)的 Token
服務(wù)端收到請(qǐng)求,然后去驗(yàn)證客戶端請(qǐng)求里面帶著的 Token,如果驗(yàn)證成功,就向客戶端返回請(qǐng)求的數(shù)據(jù)
APP登錄的時(shí)候發(fā)送加密的用戶名和密碼到服務(wù)器,服務(wù)器驗(yàn)證用戶名和密碼,如果成功,以某種方式比如隨機(jī)生成32位的字符串作為token,存儲(chǔ)到服務(wù)器中,并返回token到APP,以后APP請(qǐng)求時(shí),凡是需要驗(yàn)證的地方都要帶上該token,然后服務(wù)器端驗(yàn)證token,成功返回所需要的結(jié)果,失敗返回錯(cuò)誤信息,讓他重新登錄。其中服務(wù)器上token設(shè)置一個(gè)有效期,每次APP請(qǐng)求的時(shí)候都驗(yàn)證token和有效期。
那么我的問(wèn)題來(lái)了: 1.服務(wù)器上的token存儲(chǔ)到數(shù)據(jù)庫(kù)中,每次查詢(xún)會(huì)不會(huì)很費(fèi)時(shí)。如果不存儲(chǔ)到數(shù)據(jù)庫(kù),應(yīng)該存儲(chǔ)到哪里呢。 2.客戶端得到的token肯定要加密存儲(chǔ)的,發(fā)送token的時(shí)候再解密。存儲(chǔ)到數(shù)據(jù)庫(kù)還是配置文件呢?
token是個(gè)易失數(shù)據(jù),丟了無(wú)非讓用戶重新登錄一下,新浪微博動(dòng)不動(dòng)就讓我重新登錄,反正這事兒我是無(wú)所謂啦。
所以如果你覺(jué)得普通的數(shù)據(jù)庫(kù)表?yè)尾蛔×耍梢苑诺?MSSQL/MySQL 的內(nèi)存表里(不過(guò)據(jù)說(shuō)mysql的內(nèi)存表性能提升有限),可以放到 Memcache里(講真,這個(gè)是挺常見(jiàn)的策略),可以放到redis里(我做過(guò)這樣的實(shí)現(xiàn)),甚至可以放到 OpenResty 的變量字典里(只要你有信心不爆內(nèi)存)。
token是個(gè)憑條,不過(guò)它比門(mén)票溫柔多了,門(mén)票丟了重新花錢(qián)買(mǎi),token丟了重新操作下認(rèn)證一個(gè)就可以了,因此token丟失的代價(jià)是可以忍受的——前提是你別丟太頻繁,要是讓用戶隔三差五就認(rèn)證一次那就損失用戶體驗(yàn)了。
基于這個(gè)出發(fā)點(diǎn),如果你認(rèn)為用數(shù)據(jù)庫(kù)來(lái)保持token查詢(xún)時(shí)間太長(zhǎng),會(huì)成為你系統(tǒng)的瓶頸或者隱患,可以放在內(nèi)存當(dāng)中。
比如memcached、redis,KV方式很適合你對(duì)token查詢(xún)的需求。
這個(gè)不會(huì)太占內(nèi)存,比如你的token是32位字符串,要是你的用戶量在百萬(wàn)級(jí)或者千萬(wàn)級(jí),那才多少內(nèi)存。
要是數(shù)據(jù)量真的大到單機(jī)內(nèi)存扛不住,或者覺(jué)得一宕機(jī)全丟風(fēng)險(xiǎn)大,只要這個(gè)token生成是足夠均勻的,高低位切一下分到不同機(jī)器上就行,內(nèi)存絕對(duì)不會(huì)是問(wèn)題。
客戶端方面這個(gè)除非你有一個(gè)非常安全的辦法,比如操作系統(tǒng)提供的隱私數(shù)據(jù)存儲(chǔ),那token肯定會(huì)存在泄露的問(wèn)題。比如我拿到你的手機(jī),把你的token拷出來(lái),在過(guò)期之前就都可以以你的身份在別的地方登錄。
解決這個(gè)問(wèn)題的一個(gè)簡(jiǎn)單辦法
1、在存儲(chǔ)的時(shí)候把token進(jìn)行對(duì)稱(chēng)加密存儲(chǔ),用時(shí)解開(kāi)。
2、將請(qǐng)求URL、時(shí)間戳、token三者進(jìn)行合并加鹽簽名,服務(wù)端校驗(yàn)有效性。
這兩種辦法的出發(fā)點(diǎn)都是:竊取你存儲(chǔ)的數(shù)據(jù)較為容易,而反匯編你的程序hack你的加密解密和簽名算法是比較難的。然而其實(shí)說(shuō)難也不難,所以終究是防君子不防小人的做法。話說(shuō)加密存儲(chǔ)一個(gè)你要是被人扒開(kāi)客戶端看也不會(huì)被噴明文存儲(chǔ)……
方法1它拿到存儲(chǔ)的密文解不開(kāi)、方法2它不知道你的簽名算法和鹽,兩者可以結(jié)合食用。
但是如果token被人拷走,他自然也能植入到自己的手機(jī)里面,那到時(shí)候他的手機(jī)也可以以你的身份來(lái)用著,這你就瞎了。
于是可以提供一個(gè)讓用戶可以主動(dòng)expire一個(gè)過(guò)去的token類(lèi)似的機(jī)制,在被盜的時(shí)候能遠(yuǎn)程止損。
在網(wǎng)絡(luò)層面上token明文傳輸?shù)脑挄?huì)非常的危險(xiǎn),所以建議一定要使用HTTPS,并且把token放在post body里。
session
session的中文翻譯是“會(huì)話”,當(dāng)用戶打開(kāi)某個(gè)web應(yīng)用時(shí),便與web服務(wù)器產(chǎn)生一次session。服務(wù)器使用session把用戶的信息臨時(shí)保存在了服務(wù)器上,用戶離開(kāi)網(wǎng)站后session會(huì)被銷(xiāo)毀。這種用戶信息存儲(chǔ)方式相對(duì)cookie來(lái)說(shuō)更安全,可是session有一個(gè)缺陷:如果web服務(wù)器做了負(fù)載均衡,那么下一個(gè)操作請(qǐng)求到了另一臺(tái)服務(wù)器的時(shí)候session會(huì)丟失。
cookie
cookie是保存在本地終端的數(shù)據(jù)。cookie由服務(wù)器生成,發(fā)送給瀏覽器,瀏覽器把cookie以kv形式保存到某個(gè)目錄下的文本文件內(nèi),下一次請(qǐng)求同一網(wǎng)站時(shí)會(huì)把該cookie發(fā)送給服務(wù)器。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會(huì)被惡意使用,同時(shí)不會(huì)占據(jù)太多磁盤(pán)空間,所以每個(gè)域的cookie數(shù)量是有限的。
cookie的組成有:名稱(chēng)(key)、值(value)、有效域(domain)、路徑(域的路徑,一般設(shè)置為全局:”\”)、失效時(shí)間、安全標(biāo)志(指定后,cookie只有在使用SSL連接時(shí)才發(fā)送到服務(wù)器(https)
token
token的意思是“令牌”,是用戶身份的驗(yàn)證方式,最簡(jiǎn)單的token組成:uid(用戶唯一的身份標(biāo)識(shí))、time(當(dāng)前時(shí)間的時(shí)間戳)、sign(簽名,由token的前幾位+鹽以哈希算法壓縮成一定長(zhǎng)的十六進(jìn)制字符串,可以防止惡意第三方拼接token請(qǐng)求服務(wù)器)。還可以把不變的參數(shù)也放進(jìn)token,避免多次查庫(kù)
cookie 和session的區(qū)別
1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙
考慮到安全應(yīng)當(dāng)使用session。
3、session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能
考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。
4、單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。
5、所以個(gè)人建議:
將登陸信息等重要信息存放為SESSION
其他信息如果需要保留,可以放在COOKIE中
token 和session 的區(qū)別
session 和 oauth token并不矛盾,作為身份認(rèn)證 token安全性比session好,因?yàn)槊總€(gè)請(qǐng)求都有簽名還能防止監(jiān)聽(tīng)以及重放攻擊,而session就必須靠鏈路層來(lái)保障通訊安全了。如上所說(shuō),如果你需要實(shí)現(xiàn)有狀態(tài)的會(huì)話,仍然可以增加session來(lái)在服務(wù)器端保存一些狀態(tài)
token就是令牌,比如你授權(quán)(登錄)一個(gè)程序時(shí),他就是個(gè)依據(jù),判斷你是否已經(jīng)授權(quán)該軟件;cookie就是寫(xiě)在客戶端的一個(gè)txt文件,里面包括你登錄信息之類(lèi)的,這樣你下次在登錄某個(gè)網(wǎng)站,就會(huì)自動(dòng)調(diào)用cookie自動(dòng)登錄用戶名;session和cookie差不多,只是session是寫(xiě)在服務(wù)器端的文件,也需要在客戶端寫(xiě)入cookie文件,但是文件里是你的瀏覽器編號(hào).Session的狀態(tài)是存儲(chǔ)在服務(wù)器端,客戶端只有session id;而Token的狀態(tài)是存儲(chǔ)在客戶端。
---------------------
作者:喜歡出發(fā)
來(lái)源:CSDN
原文:https://blog.csdn.net/weixin_41918841/article/details/82227136
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!