Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DjangoとFastAPIによる 実践認証技術

shimakaze-git
September 30, 2024
200

DjangoとFastAPIによる 実践認証技術

shimakaze-git

September 30, 2024
Tweet

More Decks by shimakaze-git

Transcript

  1. お前、誰よ • 名前 ◦ 大島和輝 (X:@shimakaze_soft) ◦ 社内では「しまかぜ」と呼ばれている • Recustomer株式会社

    ◦ バックエンドエンジニア ◦ データエンジニア • 趣味 ◦ サッカー ◦ 歴史
  2. 目次 • 本トークを話そうと思ったきっかけ • 認証の基本概念 • ステートレス vs ステートフル認証 •

    Djangoにおける認証技術 • FastAPIにおける認証技術 • 実際の適用例とベストプラクティス • まとめ
  3. full-stack framework での開発の問題点 • Djangoであれば、フロントエンドのテ ンプレート機能としてDjango Templateを提供している • Laravelであれば、Bladeテンプレート というものがある

    • バックエンドもフロントエンドもあらゆる 機能を提供している分、スケーラビリ ティや開発生産性の低下などの後々 の開発に影響を与えていく 事が多い full-stack framework full-stack framework
  4. 認可(Authorization )とは何か • 認可は、システムリソースに対するユーザーのアクセスレベルを決定するプロセス。 • 認可後、システムは特定のリソースに対する許可されたユーザーのアクセスレベルを決定 する。 • ex. 書籍管理システムを例にとる

    ◦ 一般従業員は書籍情報の作成と読み取り権限はあっても、編集と削除を行う権限がない ◦ マネージャーは編集と削除権限があるなど • 認証と認可は異なるプロセスだが、密接に関係している • まず認証を行ってから、次に認可を行う
  5. ステートフル認証 • サーバー側に状態を保持する ◦ ユーザーがログインすると、サーバーがセッション IDを発行し、セッションの状態をサーバー側で管 理する。 ◦ セッション情報はサーバーのメモリやデータベースに保存され、ユーザーが再度リクエストを送る際 に、このセッションIDを使用して認証を行う。

    • 基本的にセッション IDを使用 ◦ クライアントはセッション IDをクッキーなどに保存し、 HTTPリクエストごとにサーバーへ送信する。 サーバーはこのセッション IDを参照し、ユーザーの状態を確認する。 • 大体のWEBフレームワークで実装するとデフォルトではステートフル認証になることが多い(  Django, Rails, Laravelなど)
  6. ステートレス認証 • サーバー側に状態を保持しない ◦ ステートレス認証では、サーバーがクライアントの状態を保持せず、すべてのリクエストが独立して 処理される。 ◦ ユーザーが認証された際に発行されるトークンには、ユーザー情報や認証状態が含まれており、 サーバー側で認証状態を保持する必要がない。 •

    基本的にはトークンを使用 ◦ クライアントはトークンをヘッダーなどに添付してサーバーに対してリクエストして、 サーバーはトー クンの有効性を検証する ことで認証を行う。 ◦ サーバーはトークン有効性を検証するのみで、 クライアントの状態を保持しない 。 • SPA + Web APIの構成を取る際に使用される事が多く、トークンには JWTを使用する事が多い。
  7. JWTとは • JWT (JSON Web Token) は、ユーザー認証や情報の安全な交換に用いられるコ ンパクトでURLセーフなトークン形式の文字列。 • 主にWebアプリケーションやAPIで広く使われており、認証情報やその他の情報を

    クライアントとサーバー間で安全にやり取りするために使用されます。 • JWTは、以下の3つの部分で構成されている。 ◦ ヘッダー (Header) ◦ ペイロード (Payload) ◦ 署名 (Signature)
  8. トークンをどこに保持するべきか • LocalStorage ◦ 利点 ▪ ブラウザのJavaScriptから簡単にアクセスでき、読み書きも容易。 ▪ また、リクエストごとにサーバーに自動送信されないため、 APIエンドポイントごとに必要なとき

    にヘッダーにJWTをセットして送信するなど、制御がしやすい。 ◦ リスク ▪ 懸念は、XSS(クロスサイトスクリプティング)攻撃です。悪意のあるスクリプトがサイトに注入 されると、ローカルストレージ内の JWTが盗まれるリスクがある。
  9. トークンをどこに保持するべきか • Cookie (HttpOnly) ◦ 利点 ▪ クッキーにJWTを保持し、かつHTTP-Only属性を付与することで、 JavaScriptからアクセスで きないようにし、XSS攻撃からJWTを守ることができます。また、クッキーには

    Secure属性を 付け、HTTPS通信時のみ送信されるように設定することも重要です。これにより、 CSRF(クロ スサイトリクエストフォージェリ)攻撃に対する防御も強化されます。 ◦ リスク ▪ Cookieはリクエストごとに自動で送信されるため、トークンの制御が難しく、 CSRF対策を追加 で行う必要がある。 Djangoも含めた大体のframeworkはデフォルトはSessionのCookie(HttpOnly)を使用している
  10. 認証で重要な Cookieが持つ基本的な属性 • Domain ◦ Cookieが送信される対象のドメイン。このドメインに対してのみ Cookieが送信される。 • Secure ◦

    この属性が設定されている場合、 CookieはHTTPS接続時にのみ送信される。 TrueかFalseで設定 する • HttpOnly ◦ 真偽値型(True: False) ◦ JavaScriptからアクセスできないようにする属性。この属性を設定することで、 XSS(クロスサイトス クリプティング)攻撃を防ぐことができます。 TrueかFalseで設定する • SameSite ◦ クロスサイトリクエスト時に Cookieが送信されるかどうかを制御する属性。 Strict、Lax、Noneの3つ の値があります。 ◦ 詳細は後述します。
  11. Djangoのデフォルト認証のメリットとデメリット • メリット ◦ シンプルな実装で認証を構築でき、特にカスタマイズの必要がない場合は便利 ◦ セッション管理やユーザー認証に関する機能がすべて標準で提供されている • デメリット ◦

    APIベースの認証や、フロントエンドとバックエンドが分離している構成では非効率 ◦ セッションの管理が必要であり、スケーラビリティが課題になることがある
  12. django-ninjaとdjango-restframeworkの違い • django-restframework ◦ より機能が豊富で、API開発に必要な多くの機能を提供 ◦ Djangoの認証システムやパーミッション設定などを強力にサポート ◦ DjangoでRESTfulAPIを実装する際に昔からの選択肢になりやすく資料が豊富 •

    django-ninja ◦ 最近出てきたFastAPIライクな実装ができる、パフォーマンス重視の軽量な APIライブラリ ◦ Pythonの型ヒントを活用し、型安全な開発を実現 ◦ 宣言的でシンプルな設計により、学習コストが低い ◦ 詳細は以下のトークを参考に ▪ Django Ninjaで高速なAPI開発を実現する ▪ 実践ガイドとベストプラクティス 加藤雅也 ▪ 09/27 11:40 - 11:55 (Asia/Tokyo) 20F #pyconjp_1
  13. django-ninjaでのJWT実装 • `pip install django-ninja pyjwt`を導入する ◦ django-ninja ◦ pyjwt

    • settings.pyを作成して、いくつかの変数を用意する
  14. ドメイン属性を指定する • Domain 属性を指定することで、異なるサブドメイン間でクッキーを共有することが 可能。 • Domain 属性を設定すると、指定したドメインとそのサブドメインでもクッキーを送信 できるようになります ◦

    例えば、www.test.com で設定されたクッキーは、 www.test.com 下のサーバーのみリクエストに のみ送信され、api.test.com では送信されない。 ◦ 例えば、Domain=test.com と設定すると、www.test.com, api.test.com など、test.com 以下の全 てのサブドメインでクッキーが共有 されます。
  15. ドメイン属性を指定する BackEnd WebAPI FrontEnd HTTP Request api.test.com www.test.com BackEnd WebAPI

    FrontEnd HTTP Request api.test.com www.test.com domain属性 test.com domain属性 www.test.com Cookieは付与されない
  16. SameSite属性は付与した方がいい( SameSite=Strict) Strict • Cookieはクロスサイトリクエストに一切送信されない。 • つまり、他のドメインからのリクエスト(リンクのクリックやフォーム送信など)では、そのクッキーは送信さ れず、クッキーが設定されたドメイン内でのみ有効。 • クロスサイト攻撃に非常に強い

    ◦ クッキーが送信されないため、他のサイトからの CSRF攻撃を防ぐことができる。 ◦ リンクをクリックして別のタブに遷移した場合や、他のサイトからのリクエストでクッキーが必要な場 合にも送信されないため、ユーザー体験に影響を与えることがあります。
  17. SameSite属性は付与した方がいい( SameSite=Lax) Lax • Cookieはクロスサイトリクエストでも送信されますが、安全なクロスサイトナビゲーションに限定される • 具体的には、GETメソッドのリクエストやリンクのクリックなどではクッキーが送信されるが、 POSTリクエス トや他の安全でないリクエストではクッキーが送信されない。 •

    セキュリティと利便性のバランスが取れる ◦ 通常のリンククリックや GETリクエストではクッキーが送信されるため、サイト間のナビゲーションが スムーズに行われます。 • CSRFに一定の防御 ◦ GET以外のリクエストではクッキーが送信されないため、 CSRF攻撃に対して一定の防御力を持って いる
  18. SameSite属性は付与した方がいい( SameSite=None) None • Cookieがクロスサイトリクエストにも常に送信される設定です。 • これは、iframe内やクロスサイトPOSTリクエストなど、あらゆるクロスサイトシナリオでクッキーが送信され る。 • 最も柔軟な設定

    ◦ クロスサイトリクエストにもクッキーが送信されるため、サードパーティのサービスと連携するアプリ ケーション(例:OAuthプロバイダやCDN)がこの設定を必要とすることが多いです。 • セキュリティ上のリスクが高い ◦ クッキーがクロスサイトで送信されるため、 CSRF攻撃に対して脆弱になる可能性があります。
  19. まとめ • SPA + WebAPIの構成をとる場合、ステートレスでセッション認証を行うような構成 を主に紹介 • ステートレス認証となるとJWTなどを使ったトークンがある • CookieのDomain,

    HttpOnly, Secure, SameSiteなどの属性を設定して、トークンの 持ち方はかなり重要になる • セッション認証とトークン認証の良いとこ取りをすると実装がやりやすい • 余裕があるならAuth0などを用いた実装が一番安全