使用JWT進行身份認證

什么是JWT

  • Json web token(JWT), 是為了在網(wǎng)絡應用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標準(RFC 7519)师幕。該token被設計為緊湊且安全的蛉鹿,特別適用于分布式站點的單點登錄(SSO)場景煌集。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息述雾,以便于從資源服務器獲取資源,也可以增加一些額外的其它業(yè)務邏輯所必須的聲明信息,該token也可直接被用于認證豫柬,也可被加密锌钮。

傳統(tǒng)的session認證

  • http協(xié)議本身是一種無狀態(tài)的協(xié)議桥温,而這就意味著如果用戶向我們的應用提供了用戶名和密碼來進行用戶認證,那么下一次請求時梁丘,用戶還要再一次進行用戶認證才行侵浸,因為根據(jù)http協(xié)議,我們并不能知道是哪個用戶發(fā)出的請求氛谜,所以為了讓我們的應用能識別是哪個用戶發(fā)出的請求掏觉,我們只能在服務器存儲一份用戶登錄的信息,這份登錄信息會在響應時傳遞給瀏覽器值漫,告訴其保存為cookie,以便下次請求時發(fā)送給我們的應用澳腹,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統(tǒng)的基于session認證。\r\n \r\n但是這種基于session的認證使應用本身很難得到擴展杨何,隨著不同客戶端用戶的增加酱塔,獨立的服務器已無法承載更多的用戶,而這時候基于session認證應用的問題就會暴露出來危虱。

基于session認證所顯露的問題

  • 內(nèi)存: 每個用戶經(jīng)過我們的應用認證之后羊娃,我們的應用都要在服務端做一次記錄,以方便用戶下次請求的鑒別槽地,通常而言session都是保存在內(nèi)存中迁沫,而隨著認證用戶的增多,服務端的開銷會明顯增大捌蚊。
  • 擴展性: 用戶認證之后集畅,服務端做認證記錄,如果認證的記錄被保存在內(nèi)存中的話缅糟,這意味著用戶下次請求還必須要請求在這臺服務器上,這樣才能拿到授權的資源挺智,這樣在分布式的應用上,相應的限制了負載均衡器的能力窗宦。這也意味著限制了應用的擴展能力赦颇。
  • CSRF: 因為是基于cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊赴涵。

基于token的鑒權機制

基于token的鑒權機制類似于http協(xié)議也是無狀態(tài)的媒怯,它不需要在服務端去保留用戶的認證信息或者會話信息。這就意味著基于token認證機制的應用不需要去考慮用戶在哪一臺服務器登錄了髓窜,這就為應用的擴展提供了便利扇苞。

流程上是這樣的:

  1. 用戶使用用戶名密碼來請求服務器
  2. 服務器進行驗證用戶的信息
  3. 服務器通過驗證發(fā)送給用戶一個token
  4. 客戶端存儲token欺殿,并在每次請求時附送上這個token值
  5. 服務端驗證token值,并返回數(shù)據(jù)

這個token必須要在每次請求時傳遞給服務端鳖敷,它應該保存在請求頭里脖苏, 另外,服務端要支持CORS(跨來源資源共享)策略定踱,一般我們在服務端這么做就可以了.
Access-Control-Allow-Origin: *

JWT的構成

第一部分稱為頭部(header),第二部分稱為載荷(payload)棍潘,第三部分是簽證(signature)。

header

jwt的頭部承載兩部分信息:

  • 聲明類型崖媚,這里是jwt
  • 聲明加密的算法亦歉,通常直接使用 HMAC SHA256

完整的頭部就像下面這樣的JSON:

{
'typ': 'JWT',
'alg': 'HS256'
}

然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分。

playload

載荷就是存放有效信息的地方至扰。這個名字像是特指飛機上承載的貨品鳍徽,這些有效信息包含三個部分

  • 標準中注冊的聲明
  • 公共的聲明
  • 私有的聲明

標準中注冊的聲明(建議但不強制使用) :

  • iss: jwt簽發(fā)者
  • sub: jwt所面向的用戶
  • aud: 接收jwt的一方
  • exp: jwt的過期時間,這個過期時間必須要大于簽發(fā)時間
  • nbf: 定義在什么時間之前敢课,該jwt都是不可用的
  • iat: jwt的簽發(fā)時間
  • jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊

公共的聲明: 公共的聲明可以添加任何的信息绷杜,一般添加用戶的相關信息或其他業(yè)務需要的必要信息.但不建議添加敏感信息直秆,因為該部分在客戶端可解密。

私有的聲明: 私有聲明是提供者和消費者所共同定義的聲明鞭盟,一般不建議存放敏感信息圾结,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息齿诉。
定義一個payload:

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

然后將其進行base64加密筝野,得到JWT的第二部分。

signature

jwt的第三部分是一個簽證信息粤剧,這個簽證信息由三部分組成:

  • header (base64后的)
  • payload (base64后的)
  • secret
    這個部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串歇竟,然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構成了jwt的第三部分抵恋。

將這三部分用.連接成一個完整的字符串,構成了最終的jwt焕议。

注意:secret是保存在服務器端的,jwt的簽發(fā)生成也是在服務器端的弧关,secret就是用來進行jwt的簽發(fā)和jwt的驗證盅安,所以,它就是你服務端的私鑰世囊,在任何場景都不應該流露出去别瞭。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發(fā)jwt了。

如何應用

一般是在請求頭里加入Authorization株憾,并加上Bearer標注:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

服務端會驗證token蝙寨,如果驗證通過就會返回相應的資源。整個流程就是這樣的:


jwt.png

總結

優(yōu)點

  • 因為json的通用性,所以JWT是可以進行跨語言支持的籽慢,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用
  • 因為有了payload部分浸遗,所以JWT可以在自身存儲一些其他業(yè)務邏輯所必要的非敏感信息
  • 便于傳輸,jwt的構成非常簡單箱亿,字節(jié)占用很小跛锌,所以它是非常便于傳輸?shù)?/li>
  • 它不需要在服務端保存會話信息, 所以它易于應用的擴展

注意事項

  • 不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分
  • 保護好secret私鑰届惋,該私鑰非常重要
  • 盡量使用[HTTPS]協(xié)議
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末髓帽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子脑豹,更是在濱河造成了極大的恐慌郑藏,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘩欺,死亡現(xiàn)場離奇詭異必盖,居然都是意外死亡,警方通過查閱死者的電腦和手機俱饿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門歌粥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拍埠,你說我怎么就攤上這事失驶。” “怎么了枣购?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵嬉探,是天一觀的道長。 經(jīng)常有香客問我棉圈,道長涩堤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任迄损,我火速辦了婚禮定躏,結果婚禮上,老公的妹妹穿的比我還像新娘芹敌。我一直安慰自己痊远,他們只是感情好,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般败明。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逞姿,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天辞嗡,我揣著相機與錄音,去河邊找鬼滞造。 笑死续室,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的谒养。 我是一名探鬼主播挺狰,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼买窟!你這毒婦竟也來了丰泊?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤始绍,失蹤者是張志新(化名)和其女友劉穎瞳购,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亏推,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡学赛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吞杭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罢屈。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖篇亭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锄贷,我是刑警寧澤译蒂,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站谊却,受9級特大地震影響柔昼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜炎辨,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一捕透、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碴萧,春花似錦乙嘀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至曹质,卻和暖如春婴噩,著一層夾襖步出監(jiān)牢的瞬間擎场,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工几莽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留迅办,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓章蚣,卻偏偏與公主長得像站欺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子究驴,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359