系統(tǒng)安全-JWT(JSON Web Tokens)

系統(tǒng)開發(fā)來講,安全驗證永遠是最重要的沉删,從最原始的session渐尿、cookie驗證方式,到符合restful風(fēng)格矾瑰、滿足前后端分離需求砖茸、啟用https請求,各方面都在不斷變化中殴穴。

概念

JWT是一種用于雙方之間傳遞安全信息的簡潔的凉夯、URL安全的表述性聲明規(guī)范。JWT作為一個開放的標準( RFC 7519 )采幌,定義了一種簡潔的劲够,自包含的方法用于通信雙方之間以Json對象的形式安全的傳遞信息。因為數(shù)字簽名的存在休傍,這些信息是可信的征绎,JWT可以使用HMAC算法或者是RSA的公私秘鑰對進行簽名。

  • 簡潔(Compact): 可以通過URL磨取,POST參數(shù)或者在HTTP header發(fā)送人柿,因為數(shù)據(jù)量小柴墩,傳輸速度也很快

  • 自包含(Self-contained):負載中包含了所有用戶所需要的信息,避免了多次查詢數(shù)據(jù)庫

JWT的主要應(yīng)用場景

身份認證

在這種場景下凫岖,一旦用戶完成了登陸拐邪,在接下來的每個請求中包含JWT,可以用來驗證用戶身份以及對路由隘截,服務(wù)和資源的訪問權(quán)限進行驗證扎阶。由于它的開銷非常小,可以輕松的在不同域名的系統(tǒng)中傳遞婶芭,所有目前在單點登錄(SSO)中比較廣泛的使用了該技術(shù)东臀。

信息交換

在通信的雙方之間使用JWT對數(shù)據(jù)進行編碼是一種非常安全的方式,由于它的信息是經(jīng)過簽名的犀农,可以確保發(fā)送者發(fā)送的信息是沒有經(jīng)過偽造的惰赋。

JWT的結(jié)構(gòu)

加密后jwt信息如下所示,是由.分割的三部分組成呵哨,分別為Header赁濒、Payload、Signature孟害。

其結(jié)構(gòu)看起來是這樣的

xxxxx.yyyyy.zzzzz

Header

Header包含兩部分信息拒炎,alg指加密類型,可選值為HS256挨务、RSA等等击你,typ=JWT為固定值,表示token的類型谎柄。

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

Payload

Payload是指簽名信息以及內(nèi)容丁侄,一般包括iss (發(fā)行者), exp (過期時間), sub(用戶信息), aud (接收者),以及其他信息,詳細介紹請參考官網(wǎng)朝巫。

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

Signature

Signature則為對Header鸿摇、Payload的簽名。

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

如何使用JWT劈猿?

在身份鑒定的實現(xiàn)中拙吉,傳統(tǒng)方法是在服務(wù)端存儲一個session,給客戶端返回一個cookie糙臼,而使用JWT之后庐镐,當用戶使用它的認證信息登陸系統(tǒng)之后恩商,會返回給用戶一個JWT变逃,用戶只需要本地保存該token(通常使用local storage,也可以使用cookie)即可怠堪。

當用戶希望訪問一個受保護的路由或者資源的時候揽乱,通常應(yīng)該在 Authorization 頭部使用 Bearer 模式添加JWT名眉,其內(nèi)容看起來是下面這樣:

Authorization: Bearer <token>

因為用戶的狀態(tài)在服務(wù)端的內(nèi)存中是不存儲的,所以這是一種 無狀態(tài) 的認證機制凰棉。服務(wù)端的保護路由將會檢查請求頭 Authorization 中的JWT信息损拢,如果合法,則允許用戶的行為撒犀。由于JWT是自包含的福压,因此減少了需要查詢數(shù)據(jù)庫的需要。

JWT的這些特性使得我們可以完全依賴其無狀態(tài)的特性提供數(shù)據(jù)API服務(wù)或舞,甚至是創(chuàng)建一個下載流服務(wù)荆姆。因為JWT并不使用Cookie的,所以你可以使用任何域名提供你的API服務(wù)而不需要擔(dān)心跨域資源共享問題(CORS)映凳。

image.png

在jwt官網(wǎng)胆筒,可以看到有不同語言的實現(xiàn)版本,這里使用的是java版的jjwt诈豌。話不多說仆救,直接看代碼,加解密都很簡單:

/**
  * 創(chuàng)建 jwt
  * @param id
  * @param subject
  * @param ttlMillis
  * @return
  * @throws Exception
  */
  public String createJWT(String id, String subject, long ttlMillis) throws Exception {
       SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256 ;
       long nowMillis = System. currentTimeMillis();
       Date now = new Date( nowMillis);
       SecretKey key = generalKey();
       JwtBuilder builder = Jwts. builder()
            .setId(id)
            .setIssuedAt(now)
            .setSubject(subject)
           .signWith(signatureAlgorithm, key);
       if (ttlMillis >= 0){
           long expMillis = nowMillis + ttlMillis;
           Date exp = new Date( expMillis);
           builder.setExpiration( exp);
       }
       return builder.compact();
 }


  /**
  * 解密 jwt
  * @param jwt
  * @return
  * @throws Exception
  */
  public Claims parseJWT(String jwt) throws Exception{
       SecretKey key = generalKey();
       Claims claims = Jwts. parser()
          .setSigningKey( key)
          .parseClaimsJws( jwt).getBody();
       return claims;
 }

加解密的key是通過固定字符串轉(zhuǎn)換而生成的矫渔;subject為用戶信息的json字符串彤蔽;ttlMillis是指token的有效期,時間較短庙洼,需要定時更新铆惑。

這里要介紹的token刷新方式,是在生成token的同時生成一個有效期較長的refreshToken送膳,后續(xù)由客戶端定時根據(jù)refreshToken來獲取最新的token员魏。瀏覽器與服務(wù)端之間建立sse(server send event)請求,來實現(xiàn)刷新叠聋。

參考資料:


個人介紹:

高廣超 :多年一線互聯(lián)網(wǎng)研發(fā)與架構(gòu)設(shè)計經(jīng)驗撕阎,擅長設(shè)計與落地高可用、高性能互聯(lián)網(wǎng)架構(gòu)碌补。目前就職于美團網(wǎng)虏束,負責(zé)核心業(yè)務(wù)研發(fā)工作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厦章,一起剝皮案震驚了整個濱河市镇匀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌袜啃,老刑警劉巖汗侵,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡晰韵,警方通過查閱死者的電腦和手機发乔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雪猪,“玉大人栏尚,你說我怎么就攤上這事≈缓蓿” “怎么了译仗?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長官觅。 經(jīng)常有香客問我古劲,道長,這世上最難降的妖魔是什么缰猴? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任产艾,我火速辦了婚禮,結(jié)果婚禮上滑绒,老公的妹妹穿的比我還像新娘闷堡。我一直安慰自己,他們只是感情好疑故,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布杠览。 她就那樣靜靜地躺著,像睡著了一般纵势。 火紅的嫁衣襯著肌膚如雪踱阿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天钦铁,我揣著相機與錄音软舌,去河邊找鬼。 笑死牛曹,一個胖子當著我的面吹牛佛点,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播黎比,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼超营,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阅虫?” 一聲冷哼從身側(cè)響起演闭,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颓帝,沒想到半個月后米碰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窝革,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年见间,在試婚紗的時候發(fā)現(xiàn)自己被綠了聊闯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片工猜。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡米诉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篷帅,到底是詐尸還是另有隱情史侣,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布魏身,位于F島的核電站惊橱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏箭昵。R本人自食惡果不足惜税朴,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望家制。 院中可真熱鬧正林,春花似錦、人聲如沸颤殴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涵但。三九已至杈绸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矮瘟,已是汗流浹背瞳脓。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澈侠,地道東北人篡殷。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像埋涧,于是被迫代替她去往敵國和親板辽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

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