1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[FastAPI] ライブラリを使用したCSRFトークンの実装

Last updated at Posted at 2023-01-13

この記事を読んでできること

CSRFトークンの実装ができる

やりたいこと

ログイン認証機能がないパブリックサイトでクライアントへのCSRFトークンの付与と認証をstarlette-csrfというライブラリで実装する

記述しないこと

  • FastAPIの実装について
  • Cookieについて

使用技術

バックエンド

  • Python 3.10.4
  • Fast API 0.78.0
  • starlette-csrf 1.4.4

※ トークンを発行して認証するシステムは完全にstarlette-csrfというライブラリに任せます

発行と認証の流れ(フロントとの疎通)

  1. GETメソッドでトークンを発行するAPIをフロントエンドに叩いてもらう
  2. クライアントのCookieファイルにcsrftokenというkeyでランダム文字列のトークンが格納される
  3. リクエスト毎にクライアントからx-csrftokenというkeyでヘッダーを送ってもらう
  4. ライブラリで最初に発行したものと一致するか確認し、問題がなければリクエストを通す

実装例

main.py
import os

from fastapi import FastAPI
from starlette_csrf import CSRFMiddleware
# 環境変数を含めたクラス
from config import settings

from routers import router


app = FastAPI()

# CSRFミドルウェアの設定を格納する辞書を定義します
cookie_attribute = {
    "secret": settings.SECRET_KEY,
    "cookie_samesite": None,
    "cookie_secure": True,
}

# デバッグモードではない場合、クッキーのドメインを設定します
# クッキードメインを設定します。これにより、特定のドメインにクッキーが適用されます
if not settings.DEBUG_FLAG:
    cookie_attribute["cookie_domain"] = settings.COOKIE_DOMAIN

# CSRFミドルウェアを追加し、cookie_attribute辞書を引数として渡します
app.add_middleware(CSRFMiddleware, **cookie_attribute)
app.include_router(router.router)
routers/router.py
@router.get("/api/get_csrf_token", tags=["token"])
def get_csrf_token():
    return "トークンを発行しました。"

starlette-csrfについての詳細

starlette-csrfの仕様

  • 安全なHTTPメソッド(GET、HEAD、OPTIONS、TRACE)でリクエストされた場合、set-cookie ヘッダーを使用してクライアントのクッキーに csrftoken というキーでトークンを格納する
  • クライアントがPOSTリクエストを送信する際、x-csrftoken というキーでトークンを含むヘッダーを送信することが期待される
  • サーバー側で、クッキーに保存されたトークンとヘッダーに含まれたトークンの値を比較し、検証する
  • トークンが一致する場合、リクエストは正常に処理される
  • トークンが一致しない場合は、403 Forbiddenエラーが返される

Cookie属性

READMEに詳細記載あり

  • cookieの名前
  • パス
  • Secure属性
  • Samesite属性等を変更することができる

処理の検証結果

  • 現状、単純なapi/get_csrf_tokenというエンドポイントを作成し、tokenをセットする
  • POSTMANで
    • ヘッダにx-csrftokenを用意しない場合は、403エラー
    • ヘッダにx-csrftokenを用意したが、valueが一致しない場合も403エラー
    • ヘッダにx-csrftokenを用意し、valueが一致した場合、リクエストを処理する

参考

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?