FastAPI教程 獲取當(dāng)前用戶

2021-11-03 09:47 更新

在上一章節(jié)中,(基于依賴項(xiàng)注入系統(tǒng)的)安全系統(tǒng)向路徑操作函數(shù)提供了一個(gè) str 類型的 token:

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}

但這還不是很實(shí)用。

讓我們來(lái)使它返回當(dāng)前用戶給我們。

創(chuàng)建一個(gè)用戶模型

首先,讓我們來(lái)創(chuàng)建一個(gè)用戶 Pydantic 模型。

與使用 Pydantic 聲明請(qǐng)求體的方式相同,我們可以在其他任何地方使用它:

from typing import Optional

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

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None


def fake_decode_token(token):
    return User(
        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
    )


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

創(chuàng)建一個(gè) get_current_user 依賴項(xiàng)

讓我們來(lái)創(chuàng)建一個(gè) get_current_user 依賴項(xiàng)。

還記得依賴項(xiàng)可以有子依賴項(xiàng)嗎?

get_current_user 將具有一個(gè)我們之前所創(chuàng)建的同一個(gè) oauth2_scheme 作為依賴項(xiàng)。

與我們之前直接在路徑操作中所做的相同,我們新的依賴項(xiàng) get_current_user 將從子依賴項(xiàng) oauth2_scheme 中接收一個(gè) str 類型的 token:

from typing import Optional

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

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None


def fake_decode_token(token):
    return User(
        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
    )


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

獲取用戶

get_current_user 將使用我們創(chuàng)建的(偽)工具函數(shù),該函數(shù)接收 str 類型的令牌并返回我們的 Pydantic User 模型:

from typing import Optional

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

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None


def fake_decode_token(token):
    return User(
        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
    )


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

注入當(dāng)前用戶

因此現(xiàn)在我們可以在路徑操作中使用 get_current_user 作為 Depends 了:

from typing import Optional

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

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None


def fake_decode_token(token):
    return User(
        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
    )


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

注意我們將 current_user 的類型聲明為 Pydantic 模型 User。

這將幫助我們?cè)诤瘮?shù)內(nèi)部使用所有的代碼補(bǔ)全和類型檢查。

Tip

你可能還記得請(qǐng)求體也是使用 Pydantic 模型來(lái)聲明的。

在這里 FastAPI 不會(huì)搞混,因?yàn)槟阏谑褂玫氖?nbsp;Depends。

Check

這種依賴系統(tǒng)的設(shè)計(jì)方式使我們可以擁有不同的依賴項(xiàng)(不同的「可依賴類型」),并且它們都返回一個(gè) User 模型。

我們并未被局限于只能有一個(gè)返回該類型數(shù)據(jù)的依賴項(xiàng)。

其他模型

現(xiàn)在你可以直接在路徑操作函數(shù)中獲取當(dāng)前用戶,并使用 Depends 在依賴注入級(jí)別處理安全性機(jī)制。

你可以使用任何模型或數(shù)據(jù)來(lái)滿足安全性要求(在這個(gè)示例中,使用的是 Pydantic 模型 User)。

但是你并未被限制只能使用某些特定的數(shù)據(jù)模型,類或類型。

你想要在模型中使用 id 和 email 而不使用任何的 username?當(dāng)然可以。你可以同樣地使用這些工具。

你只想要一個(gè) str?或者僅僅一個(gè) dict?還是直接一個(gè)數(shù)據(jù)庫(kù)模型類的實(shí)例?它們的工作方式都是一樣的。

實(shí)際上你沒有用戶登錄到你的應(yīng)用程序,而是只擁有訪問令牌的機(jī)器人,程序或其他系統(tǒng)?再一次,它們的工作方式也是一樣的。

盡管去使用你的應(yīng)用程序所需要的任何模型,任何類,任何數(shù)據(jù)庫(kù)。FastAPI 通過(guò)依賴項(xiàng)注入系統(tǒng)都幫你搞定。

代碼體積

這個(gè)示例似乎看起來(lái)很冗長(zhǎng)??紤]到我們?cè)谕晃募谢旌狭税踩?,?shù)據(jù)模型工具函數(shù)和路徑操作等代碼。

但關(guān)鍵的是。

安全性和依賴項(xiàng)注入內(nèi)容只需要編寫一次。

你可以根據(jù)需要使其變得很復(fù)雜。而且只需要在一個(gè)地方寫一次。但仍然具備所有的靈活性。

但是,你可以有無(wú)數(shù)個(gè)使用同一安全系統(tǒng)的端點(diǎn)(路徑操作)。

所有(或所需的任何部分)的端點(diǎn),都可以利用對(duì)這些或你創(chuàng)建的其他依賴項(xiàng)進(jìn)行復(fù)用所帶來(lái)的優(yōu)勢(shì)。

所有的這無(wú)數(shù)個(gè)路徑操作甚至可以小到只需 3 行代碼:

from typing import Optional

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

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Optional[str] = None
    full_name: Optional[str] = None
    disabled: Optional[bool] = None


def fake_decode_token(token):
    return User(
        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
    )


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    return user


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

總結(jié)

現(xiàn)在你可以直接在路徑操作函數(shù)中獲取當(dāng)前用戶。

我們已經(jīng)進(jìn)行到一半了。

我們只需要再為用戶/客戶端添加一個(gè)真正發(fā)送 username 和 password 的路徑操作。

這些內(nèi)容在下一章節(jié)。


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)