本文目錄一覽:
26.FastAPI安全性
軟體開發中,安全是永恆的話題,FastAPI作為一個優秀的Python Web開發框架,為用戶提供了多種工具,幫助用戶以標準的方式輕鬆快速地解決軟體開發中的安全性。
FastAPI 的 fastapi.security 模塊中為各種安全方案提供了一些工具,這些工具簡化了這些安全機制的使用方法。
FastAPI提供的OAuth2PasswordBearer是使用 OAuth2的密碼授權模式的Bearer Token(不記名 token) 。創建OAuth2PasswordBearer 實例需要接收URL作為參數。
客戶端會向該 URL 通過表單的格式發送 username 和 password 參數,然後得到一個 token 值;OAuth2PasswordBearer 並不會創建相應的 URL 路徑操作,只是指明了客戶端用來獲取 token 的目標 URL。
代碼示例:
在上面的代碼中, tokenUrl=”token”指的token是相對 URL 。
此時訪問,其返回結果:
上面的結果表明:訪問的內容以及被保護,必須經過授權後才可以訪問。
當獲取到表單數據後,需要進行密碼校驗,一般情況下,我們都會考慮使用哈希密碼,PassLib 是一個用於處理哈希密碼的非常好的 Python 包,它支持許多安全哈希演算法以及配合演算法使用的實用程序。
具體passlib的使用方法可以查看其文檔
下面的代碼示例在上面代碼的基礎上增加用戶登錄及Token驗證
啟動應用並執行請求:
測試無效登錄:
測試正常登錄:
返回token,在Headers中使用token訪問:
修改token後請求:
上面的代碼如果去掉 await verify_token(token) 行,則:
curl -H “Authorization:Bearer u000010007” -i
會得到返回結果,原因是默認情況下,OAuth2PasswordBearer只負責請求頭中是否具有Authorization:Bearer,如果有就會執行相應的請求,所以,為了驗證Token的正確性,需要每個方法都執行相應的驗證代碼。
本例只作為例子,在實際開發中不會直接拿用戶ID作為Token,為了提高系統的安全性,需要使用 JWT。下面我們就介紹 JWT。
JWT是一個將 JSON 對象編碼為密集且沒有空格的長字元串的標準。 具體學習和了解 JWT,請參考 。
需要提到的主要是 JWT中的sub,JWT 的規範中有一個 sub 鍵,值為該令牌的主題。使用它並不是必須的,但這是我們放置用戶標識的地方,所以一般情況下,我們在sub中存放用戶ID, 為了避免 ID 衝突,當為創建 JWT 令牌時,可以在 sub 鍵的值前加上前綴,例如 username:、userid:等。
在 Python 中生成和校驗 JWT 令牌 ,可以使用PyJWT,也可以使用 python-jose 。我們在本例中使用 python-jose 來編寫代碼。
使用:
使用 JWT,需要在系統中添加一個SECRET_KEY變數,用於生成令牌,如:
以下代碼在上面代碼的基礎上使用 JWT 令牌。
與前面的代碼差別之處:
1.生成Token的函數:build_access_token
2.校驗Token的函數:verify_token
3.登錄函數:login
請求測試:
登錄:
令牌訪問:
錯誤的令牌訪問:
在大部分應用程序中,當用戶訪問某個介面API的時候,都需要明確訪問者的身份,所以在應用程序中需要隨時獲取當前用戶,由於在 JWT 令牌的 sub 欄位中已經保存了用戶信息,所以獲取當前用戶只需要對令牌解碼即可。
在上面的代碼的基礎上,增加兩個函數,代碼如下:
請求測試:
以上,我們完成了一個簡單的安全性示例,FastAPI提供的安全性框架幫助我們節約了很多代碼,但在實際開發中,我們常常使用微服務的方式來開發,對於鑒權最好設計獨立的微服務進行處理。後面我們會展示一個採用FastAPI開發的鑒權微服務,以便在此基礎上進行業務系統的開發。
程序員應該如何設計更優雅的Token認證方式?
通過上一篇你大體已經了解session和cookie認證了,session認證需要服務端做大量的工作來保證session信息的一致性以及session的存儲,所以現代的web應用在認證的解決方案上更傾向於客戶端方向,cookie認證是基於客戶端方式的,但是cookie缺點也很明顯,到底有哪些缺點可以跳轉上一次的文章。那有沒有一種比較折中的方案呢?有的
把認證信息保存在客戶端,關鍵點就是安全的驗證,如果能解決認證信息的安全性問題,完全可以把認證信息保存在客戶端,服務端完全無認證狀態,這樣的話服務端擴展起來要方便很多。關於信息的安全解決方案,現在普遍的做法就是簽名機制,像微信公眾介面的驗證方式就基於簽名機制。
當用戶成功登陸系統並成功驗證有效之後,伺服器會利用某種機制產生一個token字元串,這個token中可以包含很多信息,例如來源IP,過期時間,用戶信息等, 把這個字元串下發給客戶端,客戶端在之後的每次請求中都攜帶著這個token,攜帶方式其實很自由,無論是cookie方式還是其他方式都可以,但是必須和服務端協商一致才可以。當然這裡我不推薦cookie。當服務端收到請求,取出token進行驗證(可以驗證來源ip,過期時間等信息),如果合法則允許進行操作。
基於token的驗證方式也是現代互聯網普通使用的認證方式,那它有什麼優點嗎?
1. 支持跨域訪問,Cookie是不允許垮域訪問的,這一點對Token機制是不存在的,前提是傳輸的用戶認證信息通過HTTP頭傳輸.
2. 無狀態:Token機制在服務端不需要存儲session信息,因為Token自身包含了所有登錄用戶的信息,只需要在客戶端的cookie或本地介質存儲狀態信息.
3. 解耦 不需要綁定到一個特定的身份驗證方案。Token可以在任何地方生成,只要在你的API被調用的時候,你可以進行Token生成調用即可.
4. 適用性更廣:只要是支持http協議的客戶端,就可以使用token認證。
5. 服務端只需要驗證token的安全,不必再去獲取登錄用戶信息,因為用戶的登錄信息已經在token信息中。
6. 基於標準化:你的API可以採用標準化的 JSON Web Token (JWT). 這個標準已經存在多個後端庫(.NET, Ruby, Java,Python,PHP)和多家公司的支持(如:Firebase,Google, Microsoft).
那基於token的認證方式有哪些缺點呢?
1. 網路傳輸的數據量增大:由於token中存儲了大量的用戶和安全相關的信息,所以比單純的cookie信息要大很多,傳輸過程中需要消耗更多流量,佔用更多帶寬,
2. 和所有的客戶端認證方式一樣,如果想要在服務端控制token的註銷有難度,而且也很難解決客戶端的劫持問題。
3. 由於token信息在服務端增加了一次驗證數據完整性的操作,所以比session的認證方式增加了cpu的開銷。
但是整體來看,基於token的認證方式還是比session和cookie方式要有很大優勢。在所知的token認證中,jwt是一種優秀的解決方案
一個JWT實際上就是一個字元串,它由三部分組成,頭部、載荷與簽名。
header典型的由兩部分組成:token的類型(「JWT」)和演算法名稱(比如:HMAC SHA256或者RSA等等)。
Payload 部分也是一個JSON對象,用來存放實際需要傳遞的數據。JWT 規定了7個官方欄位,供選用。
除了以上欄位之外,你完全可以添加自己想要的任何欄位,這裡還是提醒一下,由於jwt的標準,信息是不加密的,所以一些敏感信息最好不要添加到json裡面
為了得到簽名部分,你必須有編碼過的header、編碼過的payload、一個秘鑰(這個秘鑰只有服務端知道),簽名演算法是header中指定的那個,然對它們簽名即可。
算出簽名以後,把 Header、Payload、Signature 三個部分拼成一個字元串,每個部分之間用”點”(.)分隔,就可以返回給用戶。需要提醒一下:base64是一種編碼方式,並非加密方式。
基於token的認證方式,大體流程為:
這裡再重複一次,無論是token認證,cookie認證,還是session認證,一旦別人拿到客戶端的標識,還是可以偽造操作。所以採用任何一種認證方式的時候請考慮加入來源ip或者白名單,過期時間,另外有條件的情況下一定要使用https。
python jwt 加密為很么不行,大神幫忙瞧瞧
private_key = b’—–BEGIN PRIVATE KEY—–\nMIGEAgEAMBAGByqGSM49AgEGBS…’
‘—–BEGIN PRIVATE KEY—–\n’這後面的數據每64個字元加個\n分割一下試試
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/296014.html