前言
JWT和OAuth2.0沒(méi)有可比性,是兩個(gè)完全不同的東西。
JWT是一種認(rèn)證協(xié)議,提供了一種用于發(fā)布接入令牌(Access Token),并對(duì)發(fā)布的簽名接入令牌進(jìn)行驗(yàn)證的方法。SSO私鑰加密token。應(yīng)用端公鑰解密token,
OAuth2.0是一種授權(quán)框架,提供了一套詳細(xì)的授權(quán)機(jī)制(指導(dǎo))。用戶或應(yīng)用可以通過(guò)公開(kāi)的或私有的設(shè)置,授權(quán)第三方應(yīng)用訪問(wèn)特定資源。
一、JWT
1、JWT格式
一個(gè)JWT包含3個(gè)部分:
頭部Header:可存放簽名的類型
數(shù)據(jù)Payload:可存放用戶數(shù)據(jù)和有效期,Payload的內(nèi)容在接收者端是通過(guò)簽名(Signature)來(lái)校驗(yàn)的。
簽名Signature:使用密鑰對(duì)Header和Payload數(shù)據(jù)進(jìn)行加密生成簽名。
JWT為了便于http傳輸,3個(gè)部分需再進(jìn)行Base64Url編碼后用.
進(jìn)行關(guān)聯(lián),格式如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWT真正的好處是讓頒發(fā)JWT token的認(rèn)證服務(wù)器和校驗(yàn)JWT token的應(yīng)用服務(wù)器可以完全分開(kāi)。
那簽名是如何完成認(rèn)證功能的呢,且看:
- 用戶向認(rèn)證服務(wù)器提交用戶名和密碼,認(rèn)證服務(wù)器也可以和應(yīng)用服務(wù)器部署在一起,但往往是獨(dú)立的居多;
- 認(rèn)證服務(wù)器校驗(yàn)用戶名和密碼組合,然后創(chuàng)建一個(gè)JWT token,token的Payload里面包含用戶的身份信息,以及過(guò)期時(shí)間戳;
- 認(rèn)證服務(wù)器使用密鑰對(duì)Header和Payload進(jìn)行簽名,然后發(fā)送給客戶瀏覽器;
- 瀏覽器獲取到經(jīng)過(guò)簽名的JWT token,然后在之后的每個(gè)HTTP請(qǐng)求中附帶著發(fā)送給應(yīng)用服務(wù)器。經(jīng)過(guò)簽名的JWT就像一個(gè)臨時(shí)的用戶憑證,代替了用戶名和密碼組合,之后都是JWT token和應(yīng)用服務(wù)器打交道了;
- 應(yīng)用服務(wù)器檢查JWT簽名,確認(rèn)Payload確實(shí)是由密鑰擁有者簽過(guò)名的;
- Payload身份信息代表了某個(gè)用戶;
- 只有認(rèn)證服務(wù)器擁有私鑰,并且認(rèn)證服務(wù)器只把token發(fā)給提供了正確密碼的用戶;
- 因此應(yīng)用服務(wù)器可以認(rèn)為這個(gè)token是由認(rèn)證服務(wù)器頒發(fā)的也是安全的,因?yàn)樵撚脩艟哂辛苏_的密碼;
- 應(yīng)用服務(wù)器繼續(xù)完成HTTP請(qǐng)求,并認(rèn)為這些請(qǐng)求確實(shí)屬于這個(gè)用戶;
2、簽名和驗(yàn)簽
對(duì)于JWT,簽名方式有很多種,這里我們主要了解HS256和RS256。
HS256
HS256 使用同一個(gè)「secret_key」進(jìn)行簽名與驗(yàn)證(對(duì)稱加密)。一旦 secret_key 泄漏,就毫無(wú)安全性可言了。
- 如何使用哈希函數(shù)生成簽名?
我們拿到Header、Payload外,還要加上一個(gè)密碼,將這三個(gè)輸入值一起哈希。輸出結(jié)果是一個(gè)SHA-256 HMAC或者基于哈希的MAC。如果需要重復(fù)生成,則需要同時(shí)擁有Header、Payload和密碼才可以。這也意味著,哈希函數(shù)的輸出結(jié)果是一個(gè)數(shù)字簽名,因?yàn)檩敵鼋Y(jié)果就表示了Payload是由擁有密碼的角色生成并加簽了的,沒(méi)有其它方式可以生成這樣的輸出值了。
- 如何校驗(yàn)JWT簽名?
當(dāng)我們的服務(wù)接收到HS256簽名的JWT時(shí),我們需要使用同樣的密碼才能校驗(yàn)并確認(rèn)token里面的Payload是否有效。為了驗(yàn)證簽名,我們只需要將JWT Header和Payload以及密碼通過(guò)哈希函數(shù)生成結(jié)果。JWT的接收者需要拿到和發(fā)送者一樣的密碼值。如果我們得到的哈希結(jié)果和JWT第三部分的簽名值是一致的,則說(shuō)明有效,可以確認(rèn)發(fā)送者確實(shí)和接收者擁有相同的密碼值。
- 公式如下:
簽名Signature=Header+Payload+一個(gè)密碼 進(jìn)行SHA-256哈希;再進(jìn)行Base64Url編碼(主要方便url上傳輸)。
驗(yàn)簽: Header+Payload+一個(gè)密碼 進(jìn)行SHA-256哈希;和JWT的簽名Signature對(duì)比。
RS256
RS256 是使用 RSA 私鑰進(jìn)行簽名,使用 RSA 公鑰進(jìn)行驗(yàn)證。相比HS256更加安全。
使用RS256我們同樣需要生成一個(gè)MAC,其目的仍然是創(chuàng)建一個(gè)數(shù)字簽名來(lái)證明一個(gè)JWT的有效性。只是在這種簽名方式中,我們將創(chuàng)建token和校驗(yàn)token的能力分開(kāi),只有認(rèn)證服務(wù)器具備創(chuàng)建的能力,而應(yīng)用服務(wù)器,具備校驗(yàn)的能力。
這樣,我們需要?jiǎng)?chuàng)建兩個(gè)密鑰而不是一個(gè):
仍然需要一個(gè)私鑰,不過(guò)這次它只能被認(rèn)證服務(wù)器擁有,只用來(lái)簽名JWT。
私鑰只能用來(lái)簽名JWT,不能用來(lái)校驗(yàn)它。
第二個(gè)密鑰叫做公鑰(public key),是應(yīng)用服務(wù)器使用來(lái)校驗(yàn)JWT。
公鑰可以用來(lái)校驗(yàn)JWT,但不能用來(lái)給JWT簽名。
公鑰一般不需要嚴(yán)密保管,因?yàn)榧幢愫诳湍玫搅?,也無(wú)法使用它來(lái)偽造簽名。
- 公式如下:
簽名Signature=Header+Payload 進(jìn)行SHA-256哈希,再使用私鑰對(duì)哈希值進(jìn)行簽名;再進(jìn)行Base64Url編碼(主要方便url上傳輸)。
驗(yàn)簽: Header+Payload進(jìn)行SHA-256哈希;使用公鑰簽名Signature進(jìn)行解密,解密后的值和前面哈希值對(duì)比。
RSA的兩點(diǎn)基本原理
- 私鑰加密,持有私鑰或公鑰才可以解密
- 公鑰加密,持有私鑰才可解密
RSA公鑰、私鑰加密的使用場(chǎng)景
公鑰和私鑰都可以用于加解密操作,用公鑰加密的數(shù)據(jù)只能由對(duì)應(yīng)的私鑰解密,反之亦然。雖說(shuō)兩者都可用于加密,但是不同場(chǎng)景使用不同的密鑰來(lái)加密,規(guī)則如下:
1、私鑰用于簽名、公鑰用于驗(yàn)簽
簽名和加密作用不同,簽名并不是為了保密,而是為了保證這個(gè)簽名是由特定的某個(gè)人簽名的,而不是被其它人偽造的簽名,所以私鑰的私有性就適合用在簽名用途上。
私鑰簽名后,只能由對(duì)應(yīng)的公鑰解密,公鑰又是公開(kāi)的(很多人可持有),所以這些人拿著公鑰來(lái)解密,解密成功后就能判斷出是持有私鑰的人做的簽名,驗(yàn)證了身份合法性。
2、公鑰用于加密、私鑰用于解密,這才能起到加密作用
因?yàn)楣€是公開(kāi)的,很多人可以持有公鑰。若用私鑰加密,那所有持有公鑰的人都可以進(jìn)行解密,這是不安全的!
若用公鑰加密,那只能由私鑰解密,而私鑰是私有不公開(kāi)的,只能由特定的私鑰持有人解密,保證的數(shù)據(jù)的安全性。
二、OAuth2.0
OAuth2 有4種授權(quán)模式, 其中的access code授權(quán)碼模式在實(shí)現(xiàn)時(shí)可以使用JWT生成code, 也可以不用. 它們之間沒(méi)有必然的聯(lián)系;
-
示例1:QQ音樂(lè)使用微信登錄
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-415586.html
-
示例2:口碑使用支付寶登錄
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-415586.html
三、應(yīng)用場(chǎng)景
- OAuth2用在使用第三方賬號(hào)登錄的情況(比如使用weibo, qq, github登錄某個(gè)app)
- JWT是用在前后端分離, 需要簡(jiǎn)單的對(duì)后臺(tái)API進(jìn)行保護(hù)時(shí)使用.(前后端分離無(wú)session, 頻繁傳用戶密碼不安全)
到了這里,關(guān)于JWT和OAuth2.0的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!