microdot.auth --- HTTP 驗證

用於將路由置於 HTTP 驗證之後的裝飾器。共有兩種形式:BasicAuth 用於瀏覽器原生提示的 Authorization: Basic <base64> 機制,而 TokenAuth 用於 API 所使用的 Authorization: Bearer <token> 機制。

兩個類別皆衍生自共同的 BaseAuth 基底;應用程式會建構驗證物件,使用 authenticate() 註冊驗證回呼函式,然後以該驗證實例裝飾受保護的路由。

class BasicAuth

class microdot.auth.BasicAuth(realm: str = 'Please login', charset: str = 'UTF-8', scheme: str = 'Basic', error_status: int = 401)

HTTP Basic 驗證。當未經驗證的請求觸及受保護的路由時,瀏覽器會彈出使用者名稱/密碼對話框,並在後續請求中傳送 Authorization: Basic <base64(user:pass)>

realm

瀏覽器在提示旁顯示的領域(realm)字串。

charset

WWW-Authenticate 質詢中宣告的字元集。

scheme

驗證機制名稱。預設為 'Basic'

error_status

驗證失敗時回傳的 HTTP 狀態。預設為 401。

authenticate(f)

註冊憑證檢查的裝飾器。f 接受 (request, username, password) 並回傳經驗證的使用者物件(憑證錯誤時回傳 None)。回傳的物件會儲存於 request.g.current_user

basic = BasicAuth(realm='Camera')

@basic.authenticate
async def check(request, username, password):
    user = users.get(username)
    if user and user.check_password(password):
        return user
__call__(f)

BasicAuth 實例裝飾路由即可保護該路由::

@app.route('/admin')
@basic
def admin(request):
    return 'hello ' + request.g.current_user.name
optional(f)

__call__() 類似,但不會拒絕缺少憑證的請求 —— 處理常式仍會執行,且 request.g.current_user 會設定為經驗證的使用者或 None

class TokenAuth

class microdot.auth.TokenAuth(header: str = 'Authorization', scheme: str = 'Bearer', error_status: int = 401)

Bearer-token 驗證。用戶端在 Authorization 標頭中傳送權杖;應用程式會依其偏好的後端儲存區進行驗證。

header

攜帶權杖的標頭名稱。預設的 'Authorization' 預期值為 Bearer <token>;自訂標頭則直接攜帶權杖值。

scheme

Authorization 標頭的驗證機制。預設為 'Bearer'

error_status

驗證失敗時的 HTTP 狀態。預設為 401。

authenticate(f)

註冊權杖檢查的裝飾器。f 接受 (request, token) 並回傳使用者物件或 None::

import jwt

tokens = TokenAuth()

@tokens.authenticate
async def check(request, token):
    try:
        claims = jwt.decode(token, SECRET)
    except jwt.exceptions.PyJWTError:
        return None
    return claims['sub']
errorhandler(f)

覆寫預設 401 回應的裝飾器。f 接受 request 物件並回傳回應(或中止)。

__call__(f: Callable) Callable

TokenAuth 實例裝飾路由即可保護該路由。不具有效權杖的請求會被拒絕(預設為 401,或 errorhandler() 所回傳的內容)。成功時,經驗證的使用者位於 request.g.current_user::

@app.get('/api/me')
@tokens
async def me(request):
    return {'user': request.g.current_user}

回傳被包裝的處理常式。

optional(f: Callable) Callable

__call__() 類似,但不會拒絕缺少權杖的請求 —— 處理常式仍會執行,且 request.g.current_user 會設定為經驗證的使用者或 None。適用於那些根據呼叫端是否經過驗證而改變輸出、但不強制要求驗證的路由::

@app.get('/api/feed')
@tokens.optional
async def feed(request):
    if request.g.current_user:
        return personalized_feed(request.g.current_user)
    return public_feed()

回傳被包裝的處理常式。

class BaseAuth

class microdot.auth.BaseAuth

BasicAuthTokenAuth 的共同基底。自訂驗證機制可繼承此類別。

auth_callback: Callable | None

透過 authenticate 註冊的回呼函式。在應用程式註冊回呼函式之前為 None(以 @auth.authenticate 裝飾函式即會設定它)。

error_callback: Callable

回傳驗證失敗時所傳送回應的非同步可呼叫物件。建構函式會將其設定為回傳 401 回應的預設值;可透過 TokenAuth 上的 errorhandler 加以替換,或直接在自訂的 BaseAuth 子類別上替換。

被裝飾的路由會將其 request.g.current_user 填入驗證回呼函式所回傳的值。在路由內部,可檢查該屬性以識別呼叫端。