Flask

Flaskで実装するAPI認証・認可の基礎とJWT/OAuth2活用ガイド

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

API における認証と認可の基本概念と Flask での位置付け

Web API が外部アプリやフロントエンドとデータをやり取りする際、「誰が」 リクエストを送っているか(認証)と 「何ができる」 のか(認可)を明確にしなければなりません。
Flask はシンプルなリクエストハンドラを提供しますが、認証・認可のロジックはミドルウェアやデコレータで組み合わせて実装する必要があります。この章では代表的な 3 種類の方式と選択基準を示し、Flask での実装イメージを掴んでもらいます。

Basic 認証の概要

Basic 認証は HTTP ヘッダー Authorization: Basic <base64> にユーザー名とパスワードをそのまま送る方式です。実装は数行で済むため テスト用や内部ツール では便利ですが、平文に近い情報がネットワーク上に流れる点で 本番環境のインターネット公開 API には不向き です。

結論:導入コストは低いが、HTTPS が必須でありスケーラビリティや細かい権限管理が求められる場面では代替手段を検討すべきです。

Token 認証(JWT)とは

JSON Web Token (JWT) は 自己完結型 の文字列で、ペイロードにユーザー ID・ロール・有効期限などを署名付きで格納します。サーバーはトークンの検証だけで認可判断ができるため、ステートレスな API に最適です。

  • ステートレス:セッションストレージ不要
  • スケールしやすい:ロードバランサ配下でも同一ロジックで処理可能
  • 柔軟なクレームrole, scope などを自由に追加できる

結論:モダンな SPA やマイクロサービス間の認証に広く採用され、Flask‑JWT‑Extended が公式にサポートしています。

OAuth2 の概要と選択基準

OAuth2 は「リソースオーナーが第三者アプリにアクセス権を委譲」するフレームワークです。認可コードフロー、クライアントクレデンシャルフロー、パスワードフローなど複数のグラントタイプがありますが、現在は Implicit フローは非推奨 であり、実装から除外すべきです。

用途 推奨グラント 主なシナリオ
ユーザーが自分の Google アカウントでログイン Authorization Code Flow + PKCE SNS 連携、外部 IdP 利用
サーバ間 API 呼び出し(クライアント認証のみ) Client Credentials バックエンドサービス間
モバイル/SPA のトークン取得 Authorization Code Flow + PKCE 従来の SPA でも安全に利用可能

注記:Implicit フローはブラウザベースの攻撃サーフェスが大きく、RFC 6749 でも「非推奨」と明示されています。実装例から除外し、PKCE を必ず組み合わせた Authorization Code Flow のみを推奨します。

結論:外部 IdP(Google, Azure AD 等)と連携したい場合や 委譲認可 が必要なシステムでは OAuth2 が必須です。内部サービスだけで完結するなら JWT 単体でも十分です。


Flask‑JWT‑Extended のインストールと基本設定

この章では Flask アプリに安全な JWT 機能を組み込むまでの手順を、実務ですぐに使える形で紹介します。まずは依存パッケージの導入から、鍵管理・アルゴリズム選択まで網羅的に解説します。

ライブラリの導入手順

[crypto] オプションにより PyJWT の暗号化拡張が有効になり、HS256 以外のアルゴリズム(例: RS256)も利用可能です。

シークレットキー・アルゴリズムの設定方法

  • シークレットキーは必ず外部管理(環境変数、Vault、KMS 等)。コードベースにハードコーディングしないこと。
  • アルゴリズムはデフォルトの HS256 でも十分ですが、公開鍵方式 (RS256) にするとトークン検証を別サービスへ委譲でき、キー漏洩時の被害範囲が限定されます。

ユーザーモデル例(SQLAlchemy)とパスワードハッシュ化

  • werkzeug.securitybcrypt を内部的に利用し、ソルト管理を自動化します。
  • パスワードは決して平文で保存せず、必ずハッシュ化した値だけを DB に格納してください。

RS256 鍵管理のベストプラクティス

RS256(RSA SHA‑256)を採用する場合、公開鍵 / 秘密鍵の安全な保管とロード方法 が重要です。以下は実務で推奨される手順です。

  1. 鍵ペアの生成
    bash
    openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
    openssl rsa -pubout -in private_key.pem -out public_key.pem
  2. ファイルパーミッション
  3. private_key.pem600(所有者のみ読み取り)にし、コンテナやサーバ上でマウントする際はシークレットボリュームを使用。
  4. public_key.pem644 でも問題ありませんが、外部に漏れても安全です。
  5. 環境変数またはファイル経由で Flask に設定

python
# 環境変数に PEM 全体を格納する例(Base64 エンコード推奨)
app.config["JWT_PRIVATE_KEY"] = os.getenv("JWT_PRIVATE_KEY")
app.config["JWT_PUBLIC_KEY"] = os.getenv("JWT_PUBLIC_KEY")
app.config["JWT_ALGORITHM"] = "RS256"

または、ファイルから直接読み込む方法:

python
with open("/run/secrets/jwt_private_key.pem") as f:
app.config["JWT_PRIVATE_KEY"] = f.read()
with open("/run/secrets/jwt_public_key.pem") as f:
app.config["JWT_PUBLIC_KEY"] = f.read()

  1. ローテーション戦略
  2. 定期的に新しい鍵ペアを生成し、kid(key ID)クレームでバージョン管理。
  3. 旧鍵は一定期間保持し、既存トークンの検証ができるように「鍵リスト」方式で運用。

セキュリティ上のポイント:RSA 鍵はサイズが大きいため、環境変数やシークレット管理ツールで扱う際は Base64 エンコードし、ロード時にデコードして使用してください。


ログインエンドポイントでのトークン発行と保護ルートの実装

ここでは POST /login でアクセストークン・リフレッシュトークンを同時に発行し、以降は @jwt_required() デコレータやカスタムロールチェックでエンドポイントを保護する方法を示します。

アクセストークン・リフレッシュトークンの生成

  • identity には 最小限の情報(ユーザー ID)だけを入れ、権限はクレーム (role) として付与します。
  • 有効期限は設定ファイルで一元管理し、短めに保つことでリスクを低減できます。

@jwt_required デコレータによる認証必須エンドポイント

  • デコレータはリクエストごとにトークンの署名・有効期限を検証し、失効チェック(後述)も自動的に行います。

ロールベースアクセス制御(RBAC)の実装例

  • get_jwt() が現在のトークンから全クレームを取得し、ロール比較でアクセス制御します。
  • 必要に応じて scope クレームや複数ロール(配列)への対応も容易です。

まとめ:アクセストークンとリフレッシュトークンを分離し、@jwt_required とカスタムデコレータで RBAC を実装すれば、Flask API はシンプルかつ安全な認可層を持ちます。


トークン失効(ブラックリスト)と期限切れハンドリング

JWT は自己完結型なので「サーバ側で無効化できない」という課題があります。実務では ブラックリスト(例: Redis)を併用し、ログアウトやパスワード変更時にトークンを失効させます。

ブラックリスト方式の概要

  1. トークン生成時に jti(JWT ID)クレームが自動付与される。
  2. ログアウト・パスワード変更時に jti を Redis のセットへ保存し、TTL はトークン残存時間と同等に設定する。
  3. 各リクエストで @jwt_required() が呼び出された際に jti がブラックリストに存在すれば 無効 と判断する。

安全な Redis 接続例とエラーハンドリング

  • タイムアウト例外捕捉 を必ず入れ、接続失敗時はログに残すと同時にアプリの起動を中止させることで、ブラックリスト機能が無効になることによるセキュリティギャップを防げます。

ブラックリストチェックローダー

ログアウトエンドポイント例

トークンリフレッシュ時のエラーハンドリング(最新API)

  • @jwt_required(refresh=True) がリフレッシュトークンの有無とブラックリストチェックを自動で行います。
  • カスタムエラーハンドラを別途登録すれば、全体のレスポンスフォーマットを統一できます。

まとめ:Redis を用いたブラックリストは「即時失効」を実現する有力手段です。接続エラーへの対策と @jwt_required(refresh=True) の正しい利用で、トークンライフサイクル全体の安全性を高められます。


OAuth2 認可コードフローの簡易実装と本番環境向けセキュリティベストプラクティス

外部 IdP と連携しつつ自前 JWT を発行したいケースでは、Authlib + Flask‑JWT‑Extended の組み合わせが最もシンプルです。以下に PKCE 付き Authorization Code Flow の実装例と、運用時の重要チェックポイントをまとめます。

Authlib を使った認可コードフロー例(PKCE 必須)

  • PKCE を必ず有効化し、code_challenge_method: 'S256' を設定します。
  • エラーハンドリングを入れることで、IdP 側の認可失敗やネットワーク障害時に安全に落ちます。

JWT と OAuth2 の併用シナリオ

  1. ユーザーは外部 IdP(Google 等)で認証し Authorization Code を取得。
  2. アプリはコードをアクセストークンへ交換し、ユーザープロファイル情報 (sub, email など) を取得。
  3. 取得した情報から自前のユーザーエンティティを作成/検索し、独自 JWT(access/refresh)を発行。
  4. API 呼び出しは自前 JWT(または HttpOnly Cookie)で認証 → RBAC が適用可能。

この流れにより シングルサインオンAPI の統一トークン形式 を同時に実現できます。

本番環境向けセキュリティベストプラクティス

項目 推奨設定・実装ポイント 理由
HTTPS TLS 1.2+ を必須、全てのエンドポイントで有効化 通信の盗聴・改ざん防止
CORS Access-Control-Allow-Origin に信頼できるドメインのみを列挙 不正オリジンからの呼び出し遮断
トークン保存場所 HttpOnly, Secure Cookie を推奨(localStorage は XSS リスク) クライアント側でスクリプトが取得できない
シークレット管理 環境変数、HashiCorp Vault、AWS KMS などで暗号化保存 ソースコードに埋め込まない
署名アルゴリズム RS256(公開鍵)か HS256+長くランダムなキー 予測不可能な署名で改ざん防止
RS256 鍵配置 秘密鍵は 600 権限のファイル、またはシークレットマウントで管理
公開鍵は配布用に安全に保存
秘密鍵漏洩リスク低減
トークン失効 Redis 等でブラックリストか、短期有効期限+リフレッシュトークン利用 盗難時の被害最小化
ログ監視 jti と IP アドレスを組み合わせた異常検知ロジックを実装 不審な認証パターンを早期発見
PKCE Authorization Code フローでは必ず使用 認可コードの盗聴防止
キー・シークレットのローテーション 定期的に鍵ペア/シークレットを更新し、kid でバージョン管理 長期間同一鍵が使われ続けるリスク回避

重要:Implicit フローは非推奨です。全ての新規実装では PKCE 付き Authorization Code Flow のみを採用してください。

まとめ:Authlib と Flask‑JWT‑Extended を組み合わせ、上記ベストプラクティスに従うことで、外部 IdP とのシングルサインオンと自前 API の安全な認可基盤が構築できます。


本稿は「Basic 認証」「JWT」「OAuth2」の比較から実装例、そして運用上のセキュリティ対策まで網羅的に解説しました。読者が自プロジェクトで適切な認証方式を選択し、安全に実装できることを願っています。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Flask