成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JWT 的 Token 過期時間為什么沒有生效

開發 前端
在我第一次在 DRF(Django REST Framework)中使用 JWT 時,感覺 JWT 非常神奇,它即沒有使用 session、cookie,也不使用數據庫,僅靠一段加密的字符串,就解決了用戶身份驗證的煩惱。

[[426216]]

在我第一次在 DRF(Django REST Framework)中使用 JWT 時,感覺 JWT 非常神奇,它即沒有使用 session、cookie,也不使用數據庫,僅靠一段加密的字符串,就解決了用戶身份驗證的煩惱。

直到我遇到了一個當時百思不得解的問題,才揭開了它的神秘面紗。

當時遇到的問題就是,無論怎么設置 JWT TOKEN 的過期時間,都沒有生效,即使設置為 1 秒后過期,過了 1 分鐘,TOKEN 還是可以正常使用,重啟 Django 服務也不行。

沒有別的辦法,我就硬著頭皮去追著源碼,看看 JWT 是怎么判斷 TOKEN 是否過期的。

具體的方法就是,深度優先追溯 JWT 代碼的源頭。在 DRF 中,配置了 DEFAULT_AUTHENTICATION_CLASSES 就是 JWT:

直接定位至這個類,發現它繼承了 BaseJSONWebTOKENAuthentication

然后看 BaseJSONWebTOKENAuthentication,發現有一段判斷過期的邏輯:

繼續展開 jwt_decode_handler 這個函數,發現它調用了 jwt.decode 函數

展開 jwt.decode 函數,發現它調用了函數 _validate_claims

函數 _validate_claims 又調用了 _validate_exp,

然后展開 _validate_exp,找到了這段:

發現過期時間 exp 來自 payload,payload 又來自 TOKEN 本身:

至此謎底揭開,原來,TOKEN 的過期時間其實被編碼在了 TOKEN 本身,服務器收到 TOKEN 時先進行解碼,解碼出過期時間,然后和當前時間進行對比,如果當前時間比較小,說明沒有過期,TOKEN 就是有效的,否則返回客戶端 "Signature has expired."

我 Debug 出了這個 TOKEN 的過期時間 exp,發現這個 exp 是修改 JWT_EXPIRATION_DELTA 之前的那個過期時間,原來修改 JWT_EXPIRATION_DELTA 之后需要重新生成 TOKEN,這樣的過期時間才會按照新的來。

至此,JWT 的原理已經非常清晰了:

用戶第一次登錄時,服務器(JWT)會獲得用戶名、用戶 id,在加上設置的過期時間構建 payload:

  1. payload = { 
  2.         'user_id'user.pk, 
  3.         'username': username, 
  4.         'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA 
  5.     } 

然后將 payload 用設置好的算法使用私鑰加密成 token

  1. def jwt_encode_handler(payload): 
  2.     key = api_settings.JWT_PRIVATE_KEY or jwt_get_secret_key(payload) 
  3.     return jwt.encode( 
  4.         payload, 
  5.         key
  6.         api_settings.JWT_ALGORITHM 
  7.     ).decode('utf-8'

token 返回至客戶端后,客戶端緩存該 token,然后每一次請求時都帶上該 token。

服務器在收到請求時先驗證該 token,驗證的過程就是對 token 進行逆向解碼:

  1. def jwt_decode_handler(token): 
  2.     options = { 
  3.         'verify_exp': api_settings.JWT_VERIFY_EXPIRATION, 
  4.     } 
  5.     # get user from token, BEFORE verification, to get user secret key 
  6.     unverified_payload = jwt.decode(token, None, False
  7.     secret_key = jwt_get_secret_key(unverified_payload) 
  8.     return jwt.decode( 
  9.         token, 
  10.         api_settings.JWT_PUBLIC_KEY or secret_key, 
  11.         api_settings.JWT_VERIFY, 
  12.         options=options, 
  13.         leeway=api_settings.JWT_LEEWAY, 
  14.         audience=api_settings.JWT_AUDIENCE, 
  15.         issuer=api_settings.JWT_ISSUER, 
  16.         algorithms=[api_settings.JWT_ALGORITHM] 
  17.     ) 

解密使用同樣的算法,使用公鑰或私鑰進行解密,解密成功且不過期,則認為用戶有權限訪問,正常返回。

最后

這個問題至少花了我半個小時的時間,如果你遇到這種情況,能瞬間明白其中緣由,那本文的目的就達到了。

源碼之下無秘密,遇到問題,去看源碼可能不是解決問題最快的方法,卻是提升自己最快的方法。很多開源軟件設計模式的應用都非常值得我們學習,比如 DRF 的模塊設計,通過 mixins 組合來實現靈活可擴展的 APIView,通過子類傳入相關的 class 來實現用戶自定義的功能。如何寫出靈活可擴展、高內聚低耦合、符合開閉原則的程序,閱讀開源代碼,是一個非常高效的學習方式。

當然了,這需要先對設計模式有一個系統的學習,讓自己有一雙慧眼,不然就是守著金山不自知。

本文轉載自微信公眾號「Python七號」,可以通過以下二維碼關注。轉載本文請聯系Python七號公眾號。

 

責任編輯:武曉燕 來源: Python七號
相關推薦

2018-07-19 14:01:23

數據庫索引MySQL

2022-06-24 08:01:07

CSScontent元素

2024-02-21 21:28:29

Linux系統

2023-12-06 09:10:28

JWT微服務

2022-06-12 21:36:57

Hooksreact

2025-05-23 09:38:54

JWT開發Go

2023-12-08 12:12:21

2024-09-12 08:32:42

2021-05-19 09:37:45

SessionTokencookie

2020-07-22 07:55:12

Python開發函數

2021-08-09 08:53:30

HTTP狀態化協議

2022-09-05 08:01:20

JWTWeb安全

2009-12-04 13:31:21

PHP全局變量不能生效

2021-07-21 09:35:36

switchbreakJava

2015-04-23 10:15:53

AndroidiOS圖片

2015-04-23 10:52:53

AndroidiOS圖片

2022-05-22 21:23:10

前端監控系統

2013-03-18 09:30:18

Lisp

2020-10-20 07:49:00

JWT(JSON We

2021-03-23 10:45:23

CookieSession前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天射视频 | 日本成年免费网站 | 亚洲a毛片 | 中文一区二区 | 国产精品久久久久久久岛一牛影视 | 国产在线精品一区二区 | 毛片链接 | 亚洲精品专区 | 欧美中文字幕 | 日韩精品专区在线影院重磅 | 一区二区视频在线观看 | 日韩免费av一区二区 | 国产精品久久久久久久久久久久久久 | 男人天堂网站 | 国产三级网站 | 国产成人免费网站 | 一区二区在线免费观看 | 精品91久久久 | 粉嫩一区二区三区国产精品 | 亚洲视频免费在线观看 | 亚洲欧美日韩久久久 | 在线视频一区二区三区 | 日韩视频在线免费观看 | 国产高清av免费观看 | 免费久| 成人伊人 | 亚洲欧美一区二区在线观看 | 99日韩 | 久久免费视频1 | 天天爽夜夜骑 | 国产色| 久久精品亚洲一区二区三区浴池 | 亚洲精彩视频在线观看 | 91精品国产一区二区三区 | 天堂一区二区三区 | 视频二区在线观看 | 国产精品区二区三区日本 | 一级片av| 日日做夜夜爽毛片麻豆 | 日韩精品视频在线播放 | 99精品免费 |