0Pricing
Python Academy · レッスン

依存性注入と認証

共有ロジックと JWT ベース認証に FastAPI の DI システムを使います。

「依存性注入と認証」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

依存性注入とは

FastAPI の Depends() を使うと、共有ロジック(DB セッション、認証チェック、設定など)を宣言でき、ルートハンドラーに自動的に注入されます。

from fastapi import FastAPI, Depends
app = FastAPI()

def get_db():
    db = connect_db()
    try: yield db
    finally: db.close()

@app.get("/users")
def list_users(db = Depends(get_db)):
    return db.query_all("users")

依存関数

依存関係には、呼び出し可能なものなら何でも指定できます。関数、クラス、または別の依存関係を使用する関数にできます。

from fastapi import Depends, FastAPI
app = FastAPI()

def common_params(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

@app.get("/items")
def list_items(params: dict = Depends(common_params)):
    return params

@app.get("/users")
def list_users(params: dict = Depends(common_params)):
    return params

クラス依存関係

関連する設定をまとめるには、クラスを依存関係として使用します。クラスは __init__ の引数に依存関係が注入された状態で呼び出されます。

from fastapi import Depends, FastAPI, Query
app = FastAPI()

class Pagination:
    def __init__(self, page: int = Query(1,ge=1), size: int = Query(10,ge=1,le=100)):
        self.page = page
        self.size = size
        self.offset = (page - 1) * size

@app.get("/items")
def list_items(pag: Pagination = Depends()):
    return {"offset": pag.offset, "size": pag.size}

OAuth2 パスワードベアラー

OAuth2PasswordBearer を使用すると、Authorization ヘッダーから Bearer トークンを読み取れます。

from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()

oauth2 = OAuth2PasswordBearer(tokenUrl="/token")

@app.get("/me")
def me(token: str = Depends(oauth2)):
    return {"token": token}   # validate token here

JWT トークン

python-jose(または pyjwt)を使用して JWT トークンを作成・検証します。ログイン時にトークンを返し、保護されたすべてのルートで検証します。

# pip install python-jose passlib
from jose import jwt, JWTError

SECRET_KEY = "change-me"
ALGORITHM = "HS256"

def create_token(data: dict) -> str:
    return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM)

def verify_token(token: str) -> dict:
    return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])

現在のユーザー依存関係

JWT を検証し、認証済みユーザーを返す get_current_user 依存関係を作成します。

from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError

oauth2 = OAuth2PasswordBearer(tokenUrl="/token")

def get_current_user(token: str = Depends(oauth2)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        return payload["sub"]
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

# @app.get("/me")
# def me(user=Depends(get_current_user)): return user

パスワードのハッシュ化

平文のパスワードを保存してはいけません。passlib を使用して bcrypt でハッシュ化します。

from passlib.context import CryptContext

pwd_ctx = CryptContext(schemes=["bcrypt"], deprecated="auto")

def hash_pw(plain: str) -> str:
    return pwd_ctx.hash(plain)

def verify_pw(plain: str, hashed: str) -> bool:
    return pwd_ctx.verify(plain, hashed)

トークンエンドポイント

フォームの認証情報を受け取り、パスワードを検証して JWT を返す POST /token を実装します。

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordRequestForm
app = FastAPI()

@app.post("/token")
def login(form: OAuth2PasswordRequestForm = Depends()):
    user = get_user_by_username(form.username)
    if not user or not verify_pw(form.password, user.hashed_pw):
        raise HTTPException(status_code=401, detail="Bad credentials")
    token = create_token({"sub": form.username})
    return {"access_token": token, "token_type": "bearer"}

API キー認証

より単純なケースでは、ヘッダーまたはクエリパラメータから API キーを検証します。

from fastapi import Depends, HTTPException, Security
from fastapi.security import APIKeyHeader

API_KEY_HEADER = APIKeyHeader(name="X-API-Key")

def require_api_key(key: str = Security(API_KEY_HEADER)):
    if key != "secret-key":
        raise HTTPException(status_code=403, detail="Forbidden")
    return key

ロールベースアクセス制御

依存関係にロールチェックを追加して、認証の上に権限管理を重ねます。

from fastapi import Depends, HTTPException

def require_admin(user=Depends(get_current_user)):
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Admins only")
    return user

# @app.delete("/users/{uid}")
# def delete_user(uid: int, admin=Depends(require_admin)):

依存関係のキャッシュ

デフォルトでは、依存関係は 1 回のリクエストにつき 1 度だけ呼び出され、そのリクエスト内で使用するすべてのルート間で結果が共有されます。

# The same db session object is shared:
@app.get("/summary")
def summary(
    db = Depends(get_db),      # db resolved once
    stats = Depends(get_stats) # get_stats also uses get_db — same db instance
): ...

確認問題

FastAPI で Depends() は何をしますか。

復習

Depends(func) を使って共有ロジックを注入します。OAuth2PasswordBearer、JWTトークン、get_current_user 依存関係を使って認証を構築します。パスワードは passlib/bcrypt でハッシュ化します。さらに依存関係としてロールチェックを追加します。

よくある質問

「依存性注入と認証」レッスンは無料ですか?

はい。「依存性注入と認証」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「依存性注入と認証」で何を学びますか?

共有ロジックと JWT ベース認証に FastAPI の DI システムを使います。 ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「依存性注入と認証」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. FastAPI プロジェクトのセットアップと最初のエンドポイント
  2. パスパラメーター、クエリパラメーター、リクエストボディ
  3. 依存性注入と認証
  4. 非同期エンドポイントとデータベース連携
← Python Academyに戻る