なっトク!

FastAPIとDjangoを比べてみる

2023-06-04

たすく

きょうはFastAPIとDjangoの選び分けを、認証を軸に決めていきます

Pythonで何かを作ろうとすると、最初にここで止まります。

FastAPIか、Djangoか。

どっちも「できる」って書いてあるから、余計に決まらない

あかり
たすく

そうなんです。比較記事は機能を並べますが、両方できることを並べても選べません

なので、先に線を1本引きます。

ついでに言うと、この「選べない」は技術の話に限りません。

学生時代の問題には、正解が用意されていました。

調べれば、どれが正しいかが決まる。

大人が向き合う問題には、正解が用意されていません。

だから調べ続けても決まらず、調べること自体が目的になっていきます。

決めるために要るのは、もっと多くの情報ではありません。

「何で決めるか」という自分の基準のほうです。


結論:作るものに「画面」があるかどうか

人が見る画面まで作るなら、Django。

データを返す口だけを作るなら、FastAPI。

Djangoは「全部入り」です。

データベース、管理画面、ログイン、フォーム、画面の組み立て。

ひととおり最初から入っています。

FastAPIは「APIを作る道具」です。

画面は作りません。

その代わり、受け取って返す部分に集中しています。

だから、こういう分かれ方になります。

社内ツールを1つで完結させたい → Django。

スマホアプリやフロント側が別にあり、そこへデータを渡したい → FastAPI。


FastAPIの特徴を3つに畳むと

細かい機能表より、この3つで足りると思っています。

① 型を書くと、検査までやってくれる

「この項目は文字列」「これは数値」

そう書いておくだけで、変な値が来たときに弾いてくれます。

自分で if を並べて確かめる作業が、まるごと減ります。

② 説明書が勝手に作られる

書いた型から、APIの仕様書が自動で生成されます。

しかもブラウザ上で、その場で叩いて試せます。

これは1人で作っているときにも効きます。

3か月後の自分が、仕様を思い出せるからです。

③ 速い。ただし理由つきで

待ち時間の多い処理を、同時にさばける作りになっています。

ただし、この良さを引き出すには非同期の書き方を覚える必要があります。

ここが、最初の壁です。

速いって言われても、そこが難しいんじゃ意味ないような

あかり
たすく

そこは正直なところ、最初は普通に書いて構いません。速さが問題になってから覚えれば間に合います

なお「新しいから情報が少ない」という弱点も、よく挙げられます。

ただこれは、時間が経つほど効かなくなる種類の弱点です。

選ぶ理由としても、避ける理由としても、重く見なくていいと思っています。


認証は、どちらでもできる。違うのは「どこまで出来合いか」

ここが、この記事の中心です。

ログイン機能は、どちらでも作れます。

差は「できる/できない」ではありません。

Djangoは、完成品が入っている。

FastAPIは、部品が入っている。

Djangoには、ユーザーの入れ物、ログイン、ログアウト、パスワードの変更と再設定が最初からあります。

権限の仕組みも付いています。

つまり、認証を「使う」だけで済みます。

FastAPIは違います。

トークンを扱う道具や、認証の型は用意されています。

でも、こういう部分は自分で書きます。

  • ユーザーをどこに保存するか
  • パスワードをどう照合するか
  • トークンをいつ発行し、いつ切らすか

自由度が高いというのは、決めることが多いという意味でもあります。


「認証はDjango、APIはFastAPI」は、ありなのか

いいとこ取りをしたくなります。

ここは、はっきり書きます。

1つのアプリの中で混ぜるのは、おすすめしません。

両者は、設定の持ち方も、経路の決め方も、途中で挟む処理の仕組みも違います。

無理につなぐと、そのつなぎ目が一番壊れやすい場所になります。

どうしても分けたいなら、アプリごと分ける形になります。

認証を担当するアプリと、APIを担当するアプリを別々に立てる。

それって、大がかりじゃない?

あかり
たすく

大がかりです。動かす場所も、監視も、2つぶんになります

個人や小さなチームでやるなら、どちらかに寄せたほうが、まず間違いなく速い。


AIに認証コードを書かせたら、どうなったか

ここからが、いちばん書いておきたい話です。

「自分で書くのが面倒なら、AIに書いてもらえばいい」

そう考えるのは自然です。実際、動くコードが出てきます。

ただ、出てきたものをそのまま置くと危ない。

実際に出てきたコードには、穴が5つありました。

① ユーザーがコードの中に直書きされている

説明用の仮データです。

そのまま本番に出せば、当然ながら誰も登録できません。

これは気づける穴です。動かせば分かります。

② パスワードがそのまま比べられている

ここからが気づけない穴です。

パスワードは、そのまま保存してはいけません。

変換したもの(ハッシュ)を保存し、変換した結果どうしを比べます。

なぜか。

保存先が漏れたとき、そのまま使われてしまうからです。

しかも人は同じパスワードを使い回します。被害は自分のサービスの外まで広がります。

そして厄介なのは、この状態でも画面はふつうに動くことです。

ログインできる。エラーも出ない。テストも通る。

③ 秘密鍵がコードに書かれている

トークンの署名に使う鍵が、コード中に文字列で置かれていました。

これをそのまま保管場所に上げると、鍵を配ったのと同じです。

鍵を持っている人は、誰にでもなりすませます。

鍵は、環境変数などコードの外から読みます。

④ 壊れたトークンが来たときの処理がない

形の違うトークンを渡されると、そこで落ちます。

落ちること自体より、落ち方で中身の情報が漏れるほうが問題です。

⑤ トークンに期限がない

これは、指摘のリストにも入っていませんでした。

期限のないトークンは、一度盗まれたら永久に使えます。

パスワードを変えても、そのトークンは生き続けます。

ぜんぶ、動いてるように見えるやつばっかり……

あかり

認証の失敗は、画面に出ません。

「動いた」は、安全であることの証拠になりません。

ここが、Djangoを選ぶ最大の理由だと思っています。

Djangoの認証は、この5つを最初から踏まえた作りになっています。

自分で組まないということは、この種の穴を自分で作らないということです。


FastAPIで認証を書くなら、最低限これだけは

それでもAPIが主役なら、FastAPIで組むことになります。

そのときの持ち物リストです。

  • パスワードは専用の仕組みでハッシュ化する。自作しない
  • 秘密鍵は環境変数から読む。コードにも設定ファイルにも書かない
  • トークンには期限を入れる。短くして、必要なら更新用の仕組みを別に持つ
  • 検証の失敗は、まとめて同じ扱いにする。「ユーザーが違う」「パスワードが違う」を出し分けない
  • 通信は暗号化された経路で。トークンは、盗み見られたら終わりです

4つめは見落とされがちです。

親切に出し分けると、そのアカウントが存在すること自体を教えてしまいます。


結局、どう選ぶか

3つの問いで決まります。

① 人が見る画面まで自分で作るか

② ログイン機能に、自分で責任を持てるか

③ 相手はブラウザか、それとも別のプログラムか

①がはい、②がいいえなら、Django。

③が「別のプログラム」なら、FastAPI。

速さや流行りで選ばなくていいと思っています。

個人開発で効いてくるのは、速度ではなく「自分で守らなくていい範囲の広さ」のほうです。

たすく

ちなみに、ぼくも一度この穴を自分で作りました。動いていたので、しばらく気づきませんでした

だから今日は5つも数えられたわけね

あかり

この「自分で守らなくていい範囲を広く取る」という考え方は、学び直しそのものにも効きます。

全部を自分で背負おうとすると、まず続きません。

答えが用意されていない中でどう決めるかは、受験勉強と社会に出てからの勉強は、何が違うのかに書きました。

  • この記事を書いた人
  • 最新記事

花丸たすく

▸「思考タイプ診断」で、働き方をスマートに
▸ あなたの価値を、現実を変える力へ
▸ 「IT戦略×データ分析×プロジェクトマネジメント」の知見
▸ 京都大学卒業後、教育・情報サービス系JTCなどでDX推進・データ分析・人材開発に従事