REST framework JWT Auth

JWT

在用戶注冊或登陸后宣谈,我們想要記錄用戶的登陸狀態(tài)尔破,或者為用戶創(chuàng)建身份認證的憑證娱两。我們不再使用Session認證機制莺匠,而是使用Json Web Token 認證機制。

JWT認識

Json web token(JWT),是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開發(fā)標(biāo)準(zhǔn)十兢,該token被設(shè)計為緊湊且安全的趣竣,特別適用于分布式的單點登陸(SSO)場景。JWT的聲明一般被用來在身份提供者服務(wù)提供者之間傳遞被認證的用戶身份信息旱物,以便于從資源服務(wù)器獲取資源遥缕,也可以增加一些額外的其他業(yè)務(wù)邏輯所必須的聲明信息,該token也可以直接被用于認證宵呛,也可以被加密单匣。

傳統(tǒng)Session認證

  • http 協(xié)議本身是一種無狀態(tài)的協(xié)議,而這就意味著如果用戶向我們的應(yīng)用提供了用戶名和密碼來進行用戶認證宝穗,那么下一次請求時户秤,用戶還要再一次進行用戶認證才行。
  • 因為根據(jù)http協(xié)議逮矛,我們并不能知道是哪個用戶發(fā)出的請求鸡号,所以為了讓我們的應(yīng)用能識別是哪個用戶發(fā)出的請求。
  • 我們只能在服務(wù)器存儲一份用戶登錄的信息须鼎,這份登錄信息會在響應(yīng)時傳遞給瀏覽器鲸伴,告訴其保存為cookie,以便下次請求時發(fā)送給我們的應(yīng)用,這樣我們的應(yīng)用就能識別請求來自哪個用戶了,這就是傳統(tǒng)的基于session認證晋控。

但是這種基于session的認證使應(yīng)用本身很難得到擴展挑围,隨著不同客戶端用戶的增加,獨立的服務(wù)器已無法承載更多的用戶糖荒,而這時候基于session認證應(yīng)用的問題就會暴露出來杉辙。

基于session認證所顯露的問題

Session: 每個用戶經(jīng)過我們的應(yīng)用認證之后刮吧,我們的應(yīng)用都要在服務(wù)端做一次記錄丑搔,以方便用戶下次請求的鑒別,通常而言session都是保存在內(nèi)存中埠忘,而隨著認證用戶的增多综看,服務(wù)端的開銷會明顯增大品腹。Session:http://www.reibang.com/p/6129e376fed9

擴展性: 用戶認證之后,服務(wù)端做認證記錄红碑,如果認證的記錄被保存在內(nèi)存中的話舞吭,這意味著用戶下次請求還必須要請求在這臺服務(wù)器上,這樣才能拿到授權(quán)的資源泡垃,這樣在分布式的應(yīng)用上,相應(yīng)的限制了負載均衡器的能力羡鸥。這也意味著限制了應(yīng)用的擴展能力蔑穴。

CSRF: 因為是基于cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊惧浴。CSRF:http://www.reibang.com/p/4728b37ba1e7

基于token的鑒權(quán)機制

基于token的鑒權(quán)機制類似于http協(xié)議也是無狀態(tài)的存和,它不需要在服務(wù)端去保留用戶的認證信息或者會話信息。這就意味著基于token認證機制的應(yīng)用不需要去考慮用戶在哪一臺服務(wù)器登錄了衷旅,這就為應(yīng)用的擴展提供了便利捐腿。

流程上是這樣的:

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

這個token必須要在每次請求時傳遞給服務(wù)端茄袖,它應(yīng)該保存在請求頭里, 另外嘁锯,服務(wù)端要支持CORS(跨來源資源共享)策略绞佩,一般我們在服務(wù)端這么做就可以了Access-Control-Allow-Origin: *。CORS:https://github.com/ottoyiu/django-cors-headers/

JWT的構(gòu)成

  • 第一部分我們稱它為頭部(header)
  • 第二部分我們稱其為載荷(payload, 類似于飛機上承載的物品)
  • 第三部分是簽證(signature).

header

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

  • 聲明類型猪钮,這里是jwt
  • 聲明加密的算法 通常直接使用 HMAC SHA256

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

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

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

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

payload

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

  • 標(biāo)準(zhǔn)中注冊的聲明
  • 公共的聲明
  • 私有的聲明

標(biāo)準(zhǔn)中注冊的聲明 (建議但不強制使用) :

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

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

私有的聲明 : 私有聲明是提供者和消費者所共同定義的聲明腻要,一般不建議存放敏感信息复罐,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息雄家。

定義一個payload:

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

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

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature

JWT的第三部分是一個簽證信息趟济,這個簽證信息由三部分組成:

  • header (base64后的)
  • payload (base64后的)
  • secret

這個部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串乱投,然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構(gòu)成了jwt的第三部分顷编。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

將這三部分用.連接成一個完整的字符串,構(gòu)成了最終的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服務(wù)器端的戚炫,jwt的簽發(fā)生成也是在服務(wù)器端的,secret就是用來進行jwt的簽發(fā)和jwt的驗證媳纬,所以双肤,它就是你服務(wù)端的私鑰施掏,在任何場景都不應(yīng)該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發(fā)jwt了.

應(yīng)用

一般是在請求頭里加入Authorization茅糜,并加上Bearer標(biāo)注:

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

服務(wù)端會驗證token七芭,如果驗證通過就會返回相應(yīng)的資源。整個流程就是這樣的


image.png

總結(jié)

優(yōu)點

  • 因為json的通用性限匣,所以JWT是可以進行跨語言支持的抖苦,像JAVA,JavaScript,Node.JS,PHP等很多語言都可以使用毁菱。
  • 因為有了payload部分米死,所以JWT可以在自身存儲一些其他業(yè)務(wù)邏輯所必要的非敏感信息。
  • 便于傳輸贮庞,jwt的構(gòu)成非常簡單峦筒,字節(jié)占用很小,所以它是非常便于傳輸?shù)摹?/li>
  • 它不需要在服務(wù)端保存會話信息, 所以它易于應(yīng)用的擴展

安全相關(guān)

  • 不應(yīng)該在jwt的payload部分存放敏感信息窗慎,因為該部分是客戶端可解密的部分物喷。
  • 保護好secret私鑰,該私鑰非常重要遮斥。
  • 如果可以峦失,請使用https協(xié)議

單點登錄

單點登錄(Single Sign On),簡稱為 SSO术吗,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一尉辑。SSO的定義是在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)较屿。

server端

以server群如何生成隧魄、驗證ID的方式大致分為兩種:

  • “共享Cookie”這個就是上面提到的共享session的方式,我倒覺得叫“共享session”來得好一點隘蝎,本質(zhì)上cookie只是存儲session-id的介質(zhì)购啄,session-id也可以放在每一次請求的url里。據(jù)說這種方式不安全嘱么,我沒去細究狮含,哪位大神可以推薦下相關(guān)的資料,我后期補上曼振。其實也是辉川,畢竟session這項機制一開始就是一個server一個session的,把session拿出來讓所有server共享確實有點奇怪拴测。

  • SSO-Token方式因為共享session的方式不安全乓旗,所以我們不再以session-id作為身份的標(biāo)識。我們另外生成一種標(biāo)識集索,把它取名SSO-Token(或Ticket)屿愚,這種標(biāo)識是整個server群唯一的汇跨,并且所有server群都能驗證這個token,同時能拿到token背后代表的用戶的信息妆距。

瀏覽器端

  • 單點登錄還有非常關(guān)鍵的一步穷遂,這一步跟server端驗證token的方式無關(guān),用最早的“共享session”的方式還是現(xiàn)在的“token”方式娱据,身份標(biāo)識到了瀏覽器端都要面臨這樣的一個問題:用戶登錄成功拿到token(或者是session-id)后怎么讓瀏覽器存儲和分享到其它域名下蚪黑?同域名很簡單,把token存在cookie里中剩,把cookie的路徑設(shè)置成頂級域名下忌穿,這樣所有子域都能讀取cookie中的token。這就是共享cookie的方式(這才叫共享Cookie嘛结啼,上面那個應(yīng)該叫共享session)掠剑。比如:谷歌公司,google.com是他的頂級域名郊愧,郵箱服務(wù)的mail.google.com和地圖服務(wù)的map.google.com都是它的子域朴译。但是,跨域的時候怎么辦属铁?谷歌公司還有一個域名眠寿,youtube.com,提供視頻服務(wù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末焦蘑,一起剝皮案震驚了整個濱河市盯拱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喇肋,老刑警劉巖坟乾,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蝶防,居然都是意外死亡甚侣,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門间学,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殷费,“玉大人,你說我怎么就攤上這事低葫∠晗郏” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵嘿悬,是天一觀的道長实柠。 經(jīng)常有香客問我,道長善涨,這世上最難降的妖魔是什么窒盐? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任草则,我火速辦了婚禮,結(jié)果婚禮上蟹漓,老公的妹妹穿的比我還像新娘炕横。我一直安慰自己,他們只是感情好葡粒,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布份殿。 她就那樣靜靜地躺著,像睡著了一般嗽交。 火紅的嫁衣襯著肌膚如雪卿嘲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天轮纫,我揣著相機與錄音腔寡,去河邊找鬼焚鲜。 笑死掌唾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的忿磅。 我是一名探鬼主播糯彬,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼葱她!你這毒婦竟也來了撩扒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤吨些,失蹤者是張志新(化名)和其女友劉穎搓谆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪墅,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡泉手,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了偶器。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斩萌。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖屏轰,靈堂內(nèi)的尸體忽然破棺而出颊郎,到底是詐尸還是另有隱情,我是刑警寧澤霎苗,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布姆吭,位于F島的核電站,受9級特大地震影響唁盏,放射性物質(zhì)發(fā)生泄漏内狸。R本人自食惡果不足惜瘤睹,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望答倡。 院中可真熱鬧轰传,春花似錦、人聲如沸瘪撇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倔既。三九已至恕曲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渤涌,已是汗流浹背佩谣。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留实蓬,地道東北人茸俭。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像安皱,于是被迫代替她去往敵國和親调鬓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容