
きょうは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つも数えられたわけね

この「自分で守らなくていい範囲を広く取る」という考え方は、学び直しそのものにも効きます。
全部を自分で背負おうとすると、まず続きません。
答えが用意されていない中でどう決めるかは、受験勉強と社会に出てからの勉強は、何が違うのかに書きました。
