FastAPI教程 安全性 - 第一步

2021-11-03 09:41 更新

假設您在某個域中擁有后端API。

并且您在另一個域或同一域的不同路徑(或移動應用程序)中有一個前端。

并且您希望有一種方法讓前端使用用戶名和密碼與后端進行身份驗證。

我們可以使用OAuth2通過FastAPI來構(gòu)建它。

但是讓我們節(jié)省您閱讀完整的長規(guī)范的時間,只是為了找到您需要的那些小信息。

讓我們使用FastAPI提供的工具來處理安全性。

看起來如何

讓我們首先使用代碼看看它是如何工作的,然后我們會回來了解發(fā)生了什么。

創(chuàng)建 main.py

將示例復制到文件中main.py:

from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
    return {"token": token}

運行

信息

首先安裝python-multipart.

例如pip install python-multipart。

這是因為OAuth2使用“表單數(shù)據(jù)”來發(fā)送username和password。

使用以下命令運行示例:

uvicorn main:app --reload

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

核實

轉(zhuǎn)到交互式文檔:http : //127.0.0.1 : 8000/ docs 。

你會看到這樣的事情:

授權(quán)按鈕!

您已經(jīng)有了一個閃亮的新“授權(quán)”按鈕。

并且您的路徑操作在右上角有一個小鎖,您可以單擊它。

如果你點擊它,你會有一個小的授權(quán)表格來輸入一個username和password(和其他可選字段):

筆記

無論您在表單中輸入什么,它都不會起作用。但我們會到達那里。

這當然不是最終用戶的前端,但它是一個很好的自動工具,可以交互式地記錄所有 API。

它可以被前端團隊使用(也可以是你自己)。

它可以被第三方應用程序和系統(tǒng)使用。

它也可以由您自己使用,調(diào)試、檢查和測試相同的應用程序。

該password流

現(xiàn)在讓我們回過頭來了解這一切。

在password“流”是的方法之一(“流”)中的OAuth2所定義,手柄安全性和認證。

OAuth2 旨在使后端或 API 可以獨立于對用戶進行身份驗證的服務器。

但在這種情況下,同一個FastAPI應用程序?qū)⑻幚?API 和身份驗證。

所以,讓我們從簡化的角度來回顧一下:

  • 用戶在前端輸入username和password,然后點擊Enter。
  • 前端(在用戶的瀏覽器中運行)發(fā)送一個username和password我們的API在一個特定的URL(以申報tokenUrl="token")。
  • API 檢查username和password,并用“令牌”響應(我們還沒有實現(xiàn)任何這些)?!傲钆啤敝皇且粋€包含一些內(nèi)容的字符串,我們稍后可以使用它來驗證此用戶。通常,令牌設置為在一段時間后過期。因此,用戶稍后將不得不再次登錄。如果代幣被盜,風險就小了。它不像一個永久有效的密鑰(在大多數(shù)情況下)。
  • 前端將該令牌臨時存儲在某處。
  • 用戶單擊前端以轉(zhuǎn)到前端 Web 應用程序的另一部分。
  • 前端需要從 API 獲取更多數(shù)據(jù)。但它需要對該特定端點進行身份驗證。因此,為了使用我們的 API 進行身份驗證,它會發(fā)送Authorization一個值為Bearer加上令牌的標頭。如果令牌包含foobar,則Authorization標頭的內(nèi)容將為:Bearer foobar。

FastAPI的OAuth2PasswordBearer

FastAPI提供了幾種不同抽象級別的工具來實現(xiàn)這些安全功能。

在此示例中,我們將使用OAuth2和密碼流,使用不記名令牌。我們使用OAuth2PasswordBearer類來做到這一點。

信息

“承載”令牌不是唯一的選擇。

但這對我們的用例來說是最好的。

它可能是大多數(shù)用例的最佳選擇,除非您是 OAuth2 專家并且確切地知道為什么有另一種選擇更適合您的需求。

在這種情況下,F(xiàn)astAPI還為您提供了構(gòu)建它的工具。

當我們創(chuàng)建OAuth2PasswordBearer類的實例時,我們傳入tokenUrl參數(shù)。此參數(shù)包含客戶端(在用戶瀏覽器中運行的前端)將用于發(fā)送username和password以獲取令牌的 URL 。

from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
    return {"token": token}

提示

這里tokenUrl="token"指的token是我們尚未創(chuàng)建的相對 URL 。因為它是一個相對 URL,所以它相當于./token.

因為我們使用的是相對 URL,如果您的 API 位于https://example.com/,那么它將引用https://example.com/token。但是如果您的 API 位于https://example.com/api/v1/,那么它將引用https://example.com/api/v1/token.

使用相對 URL 很重要,以確保您的應用程序即使在像Beyond a Proxy這樣的高級用例中也能繼續(xù)工作。

此參數(shù)不會創(chuàng)建該端點/路徑操作,而是聲明該 URL/token將是客戶端應用于獲取令牌的 URL 。該信息在 OpenAPI 中使用,然后在交互式 API 文檔系統(tǒng)中使用。

我們很快也會創(chuàng)建實際的路徑操作。

信息

如果您是一個非常嚴格的“Pythonista”,您可能會不喜歡參數(shù)名稱tokenUrl而不是token_url.

那是因為它使用與 OpenAPI 規(guī)范中相同的名稱。因此,如果您需要對這些安全方案中的任何一個進行更多調(diào)查,您只需復制并粘貼它即可找到有關(guān)它的更多信息。

該oauth2_scheme變量是 的一個實例OAuth2PasswordBearer,但它也是一個“可調(diào)用的”。

它可以被稱為:

oauth2_scheme(some, parameters)

因此,它可以與Depends.

如何使用

現(xiàn)在你可以oauth2_scheme在依賴中傳遞它Depends。

from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
    return {"token": token}

這種依賴性將提供一個str被分配給所述參數(shù)token的的路徑操作功能。

FastAPI將知道它可以使用此依賴項在 OpenAPI 模式(和自動 API 文檔)中定義“安全方案”。

技術(shù)細節(jié)

FastAPI會知道它可以使用類OAuth2PasswordBearer(在依賴項中聲明)來定義 OpenAPI 中的安全方案,因為它繼承自fastapi.security.oauth2.OAuth2,而后者又繼承自fastapi.security.base.SecurityBase。

所有與 OpenAPI(和自動 API 文檔)集成的安全實用程序都繼承自SecurityBase,這就是FastAPI知道如何將它們集成到 OpenAPI 的方式。

它能做什么

它將查看該Authorization標頭的請求,檢查該值是否Bearer加上一些令牌,并將令牌作為str.

如果它沒有看到Authorization標題,或者值沒有Bearer標記,它將UNAUTHORIZED直接以 401 狀態(tài)代碼錯誤 ( )響應。

您甚至不必檢查令牌是否存在即可返回錯誤。您可以確定,如果您的函數(shù)被執(zhí)行,它將str在該令牌中包含一個。

您可以在交互式文檔中嘗試它:

我們還沒有驗證令牌的有效性,但這已經(jīng)是一個開始。

回顧

因此,只需 3 或 4 行額外的行,您就已經(jīng)擁有某種原始形式的安全性。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號