TL; DR
- 您必須驗證 JWS在服務器始終簽名。
- 客戶端簽名驗證並沒有給出太多,除非你有一個特定的情況下有意義不要這樣做。
- 您不需要驗證JWS令牌的簽名來檢查客戶端中的到期。 (除非你是在加密聲明,也就是使用JWE,在這種情況下你需要做類似的事情,因爲你需要一個密鑰來解密聲明)。
- 您不需要驗證JWS的簽名以檢查服務器中的到期日期,但是您應該這樣做,因爲這樣可以確保沒有人更改過期日期(否則驗證將失敗,因爲如果索賠更改,則重新計算的簽名將有所不同)
- 要讀取非加密聲明,您只需要解碼它們即可。您可以在客戶端使用jwt-decode。
我現在意識到,之後令牌已經過期,我的前端仍允許用戶請求我的API端點[...]
因此,要實現這個邏輯我想我需要驗證JWT令牌客戶端
如果我正確理解您,您正在討論檢查JWS是否已在客戶端過期。 爲了做到這一點,您不需要驗證令牌簽名(儘管您正在使用的庫似乎正在爲您做both things at the same time,但也可以讓您使用ignoreExpiration
標誌禁用到期控制)。 (除非您正在加密聲明,也就是使用JWE) RFC 7515 (JWS)沒有提到過期。Message Signature or MAC Validation不控制到期(並且不應該因爲簽名給你真實性和完整性)。 即使RFC 7519 (JWT)也不能控制如果JWT is valid or not已解決的到期索賠。
另外,所有的claims are optional。因此,您可以檢查JWT是否已過期或未驗證簽名,因此既不需要公共密鑰(用於RSA等非對稱加密),也不需要用於對稱加密(如AES)的密鑰(既不需要公鑰也不需要)。 在JWT和JWS令牌中,聲明只是明文base64編碼,因此您只需decode the payload without verifying if the signature is valid並閱讀到期聲明。 如果你正在加密有效載荷(又名使用JWE),那麼你將無法做到這一點。
的說明從jjwt library
JWTs可以是加密簽署(使其成爲一個JWS)或加密(使其成爲一個JWE)。
Here是從auth0一個ligthweigth庫以JWT/JWS的base64encoded聲明令牌解碼。 一個男人甚至問起checking expiration。
我不知道你爲什麼認爲你應該做這個控制客戶端,唯一的好處是避免發送客戶端知道會失敗的API請求。並且他們應該失敗,因爲服務器應該驗證令牌未過期,以前的簽名驗證(帶有祕密/私鑰)顯然。
的RFC 7519說了解這個要求:
的「EXP」(到期時間)根據權利要求標識過期時間上 或在此之後,JWT 必須不用於處理被接受。
在一個Web應用程序中,您說的令牌的使用是允許無狀態服務器對客戶端請求進行身份驗證。 可選到期聲明的目標是允許服務器對生成的JWS進行一些控制(如果我們使用JWT進行身份驗證,則必須簽署它們,因此我們應該談論JWS)。
沒有到期,令牌將永久生效或直到用於簽名的密鑰更改(這將使驗證過程失敗)。 順便說一下,invalidatingsessions是使用無狀態身份驗證最臭名昭着的缺點之一。
如果我們在用於授權的JWS有效負載(又名聲明)中包含信息(例如用戶擁有哪些角色),則會話失效成爲一個實際問題。
從Stop using JWT for sessions
,但更嚴重的是,它也可以指人與管理員的角色令牌,即使你只是吊銷了其管理角色。因爲你也不能無效令牌,有沒有辦法爲你免除他們的管理員權限
到期控制的不解決這個問題,我認爲是更注重以避免會話劫持或CSRF攻擊。
使用CSRF的攻擊者將能夠使用過期的JWS向您的API發出請求,以跳過到期控制。
另一個問題是使用公鑰或密鑰驗證客戶端中的簽名。
關於你的問題
我使用似乎都需要一個公共密鑰使用它來驗證()函數。我似乎沒有公鑰,只有一個祕密,我只是編了一個祕密,所以它不是用一對產生的。
您指出的驗證方法明確指出它接受公鑰或密鑰。
jwt.verify(token, secretOrPublicKey, [options, callback])
secretOrPublicKey是RSA和ECDSA
字符串或它可以包含HMAC算法的祕密,或PEM緩衝編碼的公共密鑰我假設你既沒有使用,你使用的是像'shhhh'字符串。
var token = jwt.sign({ data: '¿Donde esta Santiago?'}, 'shhhh');
那麼你應該做的
var decoded = jwt.verify(token, 'shhhhh');
然而,這裏的問題是:是否真的需要客戶端簽名驗證?
我想不是,至少不是這種類型的應用程序,其中客戶端只是使用JWS發送後續請求到服務器說:「嘿服務器,我是加百列,我在這裏有一個紙張(令牌)這可以保證你的文件是由你簽署的。「 因此,如果客戶端不驗證JWS並且MITM已成功向該客戶端發送了由他自己簽名的JWS(而不是由服務器簽名的JWS),則後續請求將會失敗。 像到期控制一樣,簽名驗證只能防止客戶端發出失敗的請求。
現在,客戶端驗證需要發送公鑰或密鑰。 發送公鑰並不代表安全問題,但它是額外的努力和處理,沒有什麼好處。
發送密鑰(如'shhhh')可能代表安全問題,因爲是用於簽署令牌的相同密鑰。