搜尋
首頁後端開發Python教學具有依賴注入的 FastAPI 身份驗證

FastAPI Auth with Dependency Injection

FastAPI 是一個用於在 Python 中建立 API 的現代 Web 框架。它是我個人最喜歡的 Web 框架之一,因為它內建了對 OpenAPI 規範的支援(這意味著您可以編寫後端程式碼並從中生成所有內容),並且它支援依賴注入

在這篇文章中,我們將簡要介紹一下 FastAPI 的 Depends 是如何運作的。然後我們將了解為什麼它如此適用於身份驗證和授權。我們還將它與中間件進行對比,中間件是身份驗證的另一個常見選項。最後,我們將了解 FastAPI 中一些更進階的授權模式。

什麼是依賴注入?

FastAPI 更強大的功能之一是它對依賴注入的一流支援。我們有一個更長的指南這裡,但讓我們來看一個如何使用它的快速範例。

假設我們正在建立一個分頁 API。每個API呼叫可以包括page_number和page_size。現在,我們可以建立一個 API 並直接傳入這些參數:

@app.get("/things/")
async def fetch_things(page_number: int = 0, page_size: int = 100):
    return db.fetch_things(page_number, page_size)

但是,我們可能想要加入一些驗證邏輯,這樣就沒有人要求 page_number -1 或 page_size 10,000,000。

@app.get("/things/")
async def fetch_things(page_number: int = 0, page_size: int = 100):
    if page_number  100:
        raise HTTPException(status_code=400, detail="Page size can be at most 100")
    return db.fetch_things(page_number, page_size)

這…很好,但如果我們有 10 個 API 或 100 個 API 都需要相同的分頁參數,那就有點無聊了。這就是依賴注入的用武之地 - 我們可以將所有這些邏輯移至一個函數中,並將該函數注入到我們的 API 中:

async def paging_params_dep(page_number: int = 0, page_size: int = 100):
    if page_number  100:
        raise HTTPException(status_code=400, detail="Page size can be at most 100")
    return PagingParams(page_number, page_size)

@app.get("/things/")
async def fetch_things(paging_params: PagingParams = Depends(paging_params_dep)):
    return db.fetch_things(paging_params)

@app.get("/other_things/")
async def fetch_other_things(paging_params: PagingParams = Depends(paging_params_dep)):
    return db.fetch_other_things(paging_params)

這有一些不錯的好處:

  • 每條採用 PagingParams 的路由都會自動驗證並具有預設值。

  • 它比每條路由的第一行是 validate_paging_params(page_number, page_size)

  • 更簡潔,更容易出錯
  • 這仍然適用於 FastAPI 的 OpenAPI 支援 - 這些參數會顯示在您的 OpenAPI 規格中。

這與身分驗證有什麼關係?

事實證明,這也是一種建模身份驗證的好方法!想像你有一個像這樣的函數:

async def validate_token(token: str):
    try:
        # This could be JWT validation, looking up a session token in the DB, etc.
        return await get_user_for_token(token)
    except:
        return None

要將其連接到 API 路由,我們需要做的就是將其包裝在依賴項中:

async def require_valid_token_dep(req: Request):
    # This could also be a cookie, x-api-key header, etc.
    token = req.headers["Authorization"]
    user = await validate_token(token)
    if user == None:
        raise HTTPException(status_code=401, detail="Unauthorized")
    return user

然後我們所有受保護的路由都可以添加此依賴項:

@app.get("/protected")
async def do_secret_things(user: User = Depends(require_valid_token_dep)):
    # do something with the user

如果使用者提供了有效的令牌,則該路由將運行並設定使用者。否則,將返回 401。

注意:OpenAPI/Swagger 確實對指定身份驗證令牌具有一流的支持,但您必須使用其中一個專用類別。您可以使用 fastapi.security 中的 HTTPBearer(auto_error=False) 來取代 req.headers["Authorization"],它會傳回 HTTPAuthorizationCredentials。

中介軟體與 Depends for Auth

FastAPI 與大多數框架一樣,有一個中間件 的概念。您的中間件可以包含將在請求之前和之後運行的程式碼。它可以在請求到達您的路由之前修改請求,也可以在回應傳回給使用者之前修改回應。

在許多其他框架中,中間件是進行身份驗證檢查的非常常見的地方。然而,這通常是因為中間件也負責將使用者「注入」到路由中。例如,Express 中的常見模式是執行以下操作:

app.get("/protected", authMiddleware, (req, res) => {
    // req.user is set by the middleware
    // as there's no good way to pass in extra information into this route,
    // outside of the request
});

由於FastAPI具有內建的注入概念,因此您可能根本不需要使用中介軟體。如果您需要定期「刷新」您的身份驗證令牌(以使其保持活動狀態)並將回應設定為 cookie,我會考慮使用中間件。

在這種情況下,您需要使用 request.state 將資訊從中間件傳遞到路由(如果您願意,您可以使用依賴項來驗證 request.state)。

否則,我會堅持使用 Depends,因為用戶將直接注入到您的路由中,而不需要通過 request.state。

授權 - 多租用戶、角色和權限

如果我們應用迄今為止所學到的一切,添加多租戶、角色或權限可能會非常簡單。假設我們為每個客戶都有一個唯一的子網域,我們可以為該子網域建立依賴關係:

async def tenant_by_subdomain_dep(request: Request) -> Optional[str]:
    # first we get the subdomain from the host header
    host = request.headers.get("host", "")
    parts = host.split(".")
    if len(parts) 



<p>我們可以將這個想法與先前的想法結合起來,製作一個新的「多租戶」依賴:<br>
</p>

<pre class="brush:php;toolbar:false">async def get_user_and_tenant_for_token(
    user: User = Depends(require_valid_token_dep),
    tenant: Tenant = Depends(tenant_by_subdomain_dep),
) -> UserAndTenant:
    is_user_in_tenant = await check_user_is_in_tenant(tenant, user)
    if is_user_in_tenant:
        return UserAndTenant(user, tenant)
    raise HTTPException(status_code=403, detail="Forbidden")

然後我們可以將此依賴項注入到我們的路由中:

@app.get("/protected")
async def do_secret_things(user_and_tenant: UserAndTenant = Depends(get_user_and_tenant_for_token)):
    # do something with the user and tenant

這最終會做一些主要的事情:

  • 檢查使用者是否擁有有效令牌

  • 檢查使用者是否正在向有效的子網域發出請求

  • 檢查使用者是否應該有權利存取該子網域

If any of those invariants aren’t met - an error is returned and our route will never run. We can extend this to include other things like roles & permissions (RBAC) or making sure the user has a certain property set (active paid subscription vs no active subscription).

PropelAuth

At PropelAuth, we’re big fans of FastAPI. We have a FastAPI library that will enable you to set up authentication and authorization quickly - including SSO, Enterprise SSO / SAML, SCIM Provisioning, and more.

And it all works with dependencies like the ones you’ve seen above, e.g.:

@app.get("/")
async def root(current_user: User = Depends(auth.require_user)):
    return {"message": f"Hello {current_user.user_id}"}

You can find out more here.

Summary

  • FastAPI's dependency injection provides a powerful way to handle authentication and authorization in web applications.

  • The Depends feature allows for clean, reusable code for validating tokens, checking user permissions, and handling multi-tenancy.

  • Compared to middleware, using dependencies for auth offers more flexibility and direct integration with route functions.

  • Complex authorization scenarios like multi-tenancy and role-based access control can be efficiently implemented using nested dependencies.

  • PropelAuth offers a FastAPI library that simplifies the implementation of advanced authentication and authorization features.

以上是具有依賴注入的 FastAPI 身份驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何使用Python查找文本文件的ZIPF分佈如何使用Python查找文本文件的ZIPF分佈Mar 05, 2025 am 09:58 AM

本教程演示如何使用Python處理Zipf定律這一統計概念,並展示Python在處理該定律時讀取和排序大型文本文件的效率。 您可能想知道Zipf分佈這個術語是什麼意思。要理解這個術語,我們首先需要定義Zipf定律。別擔心,我會盡量簡化說明。 Zipf定律 Zipf定律簡單來說就是:在一個大型自然語言語料庫中,最頻繁出現的詞的出現頻率大約是第二頻繁詞的兩倍,是第三頻繁詞的三倍,是第四頻繁詞的四倍,以此類推。 讓我們來看一個例子。如果您查看美國英語的Brown語料庫,您會注意到最頻繁出現的詞是“th

我如何使用美麗的湯來解析HTML?我如何使用美麗的湯來解析HTML?Mar 10, 2025 pm 06:54 PM

本文解釋瞭如何使用美麗的湯庫來解析html。 它詳細介紹了常見方法,例如find(),find_all(),select()和get_text(),以用於數據提取,處理不同的HTML結構和錯誤以及替代方案(SEL)

python中的圖像過濾python中的圖像過濾Mar 03, 2025 am 09:44 AM

處理嘈雜的圖像是一個常見的問題,尤其是手機或低分辨率攝像頭照片。 本教程使用OpenCV探索Python中的圖像過濾技術來解決此問題。 圖像過濾:功能強大的工具圖像過濾器

如何使用TensorFlow或Pytorch進行深度學習?如何使用TensorFlow或Pytorch進行深度學習?Mar 10, 2025 pm 06:52 PM

本文比較了Tensorflow和Pytorch的深度學習。 它詳細介紹了所涉及的步驟:數據準備,模型構建,培訓,評估和部署。 框架之間的關鍵差異,特別是關於計算刻度的

Python中的平行和並發編程簡介Python中的平行和並發編程簡介Mar 03, 2025 am 10:32 AM

Python是數據科學和處理的最愛,為高性能計算提供了豐富的生態系統。但是,Python中的並行編程提出了獨特的挑戰。本教程探討了這些挑戰,重點是全球解釋

如何在Python中實現自己的數據結構如何在Python中實現自己的數據結構Mar 03, 2025 am 09:28 AM

本教程演示了在Python 3中創建自定義管道數據結構,利用類和操作員超載以增強功能。 管道的靈活性在於它能夠將一系列函數應用於數據集的能力,GE

python對象的序列化和避難所化:第1部分python對象的序列化和避難所化:第1部分Mar 08, 2025 am 09:39 AM

Python 對象的序列化和反序列化是任何非平凡程序的關鍵方面。如果您將某些內容保存到 Python 文件中,如果您讀取配置文件,或者如果您響應 HTTP 請求,您都會進行對象序列化和反序列化。 從某種意義上說,序列化和反序列化是世界上最無聊的事情。誰會在乎所有這些格式和協議?您想持久化或流式傳輸一些 Python 對象,並在以後完整地取回它們。 這是一種在概念層面上看待世界的好方法。但是,在實際層面上,您選擇的序列化方案、格式或協議可能會決定程序運行的速度、安全性、維護狀態的自由度以及與其他系

Python中的數學模塊:統計Python中的數學模塊:統計Mar 09, 2025 am 11:40 AM

Python的statistics模塊提供強大的數據統計分析功能,幫助我們快速理解數據整體特徵,例如生物統計學和商業分析等領域。無需逐個查看數據點,只需查看均值或方差等統計量,即可發現原始數據中可能被忽略的趨勢和特徵,並更輕鬆、有效地比較大型數據集。 本教程將介紹如何計算平均值和衡量數據集的離散程度。除非另有說明,本模塊中的所有函數都支持使用mean()函數計算平均值,而非簡單的求和平均。 也可使用浮點數。 import random import statistics from fracti

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)