pip install fastapi python-jose[cryptography] passlib[bcrypt] uvicorn python-multipart
JWTは、クライアント側に渡すデータ(アクセストークン)の中にユーザ情報を持たせるもの。ユーザ情報を入れたjsonをエンコードしたもの。
JWTの文字列は以下のように構成されている。(参考)
<ヘッダーをエンコードした文字列>.<ペイロードをエンコードした文字列>.<署名をエンコードした文字列>
アクセストークンを保存する場所の選択肢は以下の通り
手法 | 説明 |
---|---|
localStorage | XSS攻撃に合う可能性があるためここに保存してはいけない。 |
sessionStorage | XSS攻撃に合う可能性があるためここに保存してはいけない。タブを閉じると消える。 |
cookie | httpOnly Cookieに保存する。httpOnly CokkieだとJSからCokkieを参照できなくなるらしい。CSRF攻撃対策をする必要あり。 |
JWTを認証で使いたいなら、セキュリティ面から、http-only cookiesにJWTトークンを保存しておくべき。でもそれだとsession idをhttp-only cookiesに保存しておくのと機能的にあんまり変わらない。(参考)
いや、やっぱり認証にJWTは使うな。認証情報はサーバサイドで管理しろ。(参考)
- nyandora(nyandora). JWTは使うべきではない 〜 SPAにおける本当にセキュアな認証方式 〜. Qiita.
- Shota Nukumizu. JWT認証のベストプラクティス 5選. Zenn.
長い期間保持したいデータを管理するのにJWTを使うな。JWTトークンとsessionを組み合わせて使え。
一方で、クライアント側に渡すデータにユーザ情報を持たせず、サーバ側でユーザ情報を保持しておく方法もある。これはセッションidを使う方法。
認証についての参考記事
fastapiでcookiesにデータを保存・取り出す方法
セッションIDの利用において、XSSを前提とするならHttpOnly Cookieであっても攻撃者はセッションを利用して攻撃可能(Cookieはブラウザが自動でリクエストに付加してしまうから)なのでWebStorageと大差がない
http-only cookiesはオリジンを気にしないので、session idをcookiesに保存している状態で、もしめっちゃ似せたサイトにアクセスしてしまったらsession idを送信してしまうということか?それならSameSite=Strictにしておけば対策できるということ?
セッションを使った認証は公式もやってなかったし、fastapi-sessionsっていうライブラリがあったけどメンテナンスされていなかった。 自前でセッションを使った認証を開発することもできるけどあんまりよろしくない。
だからセッションを使った認証をしたいのならFlask or Djangoを使った方がいい。
ただFlaskはSwaggerの画面がなさそうだから結局Django REST Frameworkをバックエンドで使った方が良さそう。