Contents
DRF標準認証メカニズムの概要
DRFにはTokenAuthenticationやSessionAuthenticationといった複数の認証スキームがデフォルトで提供されています。それぞれの特徴を理解することで、プロジェクトに最適な選択が可能です。
TokenAuthenticationの仕組み
TokenAuthenticationはAPIクライアントがトークンをリクエストヘッダに含めて認証する方法です。トークンはDjangoのTokenモデルに保存され、ユーザーと1:1で関連付けられます。
- 例:
Authorization: Token abcdef123456
SessionAuthenticationの特徴
SessionAuthenticationはブラウザベースの認証に適しており、セッションIDをクッキー経由で管理します。ただしAPI通信には非推奨であり、主にフロントエンドと連携する場合のみ使用されます。
認証プロバイダの選択基準
| プロバイダ | 用途例 | 推奨環境 |
|---|---|---|
| TokenAuthentication | API通信(SPA、モバイルアプリ) | ✔️ |
| SessionAuthentication | ブラウザベース認証(Django Adminなど) | ✔️ |
| BasicAuthentication | 試験用(生産環境では使用不可) | ⚠️ |
JWT認証とカスタムユーザモデルの連携
カスタムユーザーモデルを採用している場合、JWTライブラリ(例: simplejwt)との連携に注意が必要です。
AUTH_USER_MODELの設定方法
プロジェクト初期設定時に以下の設定を行う必要があります。
settings.py
|
1 2 |
AUTH_USER_MODEL = 'accounts.CustomUser' |
SimpleJWTの拡張ポイント
simplejwtをカスタムユーザモデルに対応させるには、トークン生成時のユーザー取得ロジックをオーバライドします。
serializers.py
|
1 2 3 4 5 6 7 8 9 |
from rest_framework_simplejwt.tokens import RefreshToken def get_tokens_for_user(user): refresh = RefreshToken.for_user(user) return { 'refresh': str(refresh), 'access': str(refresh.access_token), } |
使用例(トークン発行)
|
1 2 3 4 5 6 7 8 9 |
from rest_framework_simplejwt.views import TokenObtainPairView class CustomTokenObtainPairView(TokenObtainPairView): def post(self, request, *args, **kwargs): response = super().post(request, *args, **kwargs) user = request.user tokens = get_tokens_for_user(user) return Response(tokens) |
トークン発行時のカスタマイズ
カスタムフィールド(例: 社員番号)をトークンに含めたい場合は、TokenObtainPairSerializerを拡張します。
Custom Authenticationクラスの作成手順
独自の認証ロジックを実装するには、rest_framework.authentication.BaseAuthenticationを継承したクラスを作成します。
BaseAuthenticationクラスの継承
カスタム認証クラスは以下のように定義されます。
custom_auth.py
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class CustomTokenAuth(BaseAuthentication): def authenticate(self, request): token = request.headers.get('X-Custom-Token') if not token: return None # トークン検証ロジック(例: データベース照合) try: user = User.objects.get(custom_token=token) except User.DoesNotExist: raise AuthenticationFailed("無効なトークンです") return (user, None) # 認証成功時 |
authenticateメソッドの実装手順
- リクエストから認証情報を取得(例:
X-Custom-Token) - 取得した情報をセキュリティ的に検証(データベース照合など)
- 検証失敗時は
AuthenticationFailed例外を送出
認証失敗時の例外処理
|
1 2 |
raise AuthenticationFailed("トークンが見つかりません") |
認証情報のリクエスト組み込み方法
リクエストに認証情報を含める方法には、HTTPヘッダやクエリパラメータなどがあります。セキュリティ観点から最も推奨されるのはHTTPヘッダでの送信です。
HTTPヘッダでのトークン送信
Authorizationヘッダを使用するのが一般的ですが、独自のヘッダ名(例: X-Custom-Token)も利用可能です。
|
1 2 3 |
GET /api/data/ HTTP/1.1 X-Custom-Token: abc123xyz |
セキュリティ対策:ヘッダの署名検証
カスタムヘッダーを送信する際は、ヘッダの署名(例: HMAC)で改ざんを防ぐ必要があります。具体的な実装手順は以下の通りです。
- 送信元が認証情報を生成し、秘密鍵を使用してヘッダに署名
- 受信側では署名を検証し、無効な場合認証失敗とする
クエリパラメータの使用注意点
クエリパラメータでトークンを送信する方法は、セキュリティリスクが高いため推奨されません。
|
1 2 |
GET /api/data/?token=abc123xyz HTTP/1.1 |
セキュリティ上の注意点と実装ガイドライン
認証処理を設計する際には、以下の点に特に注意が必要です。
トークンの有効期限管理
トークンの有効期限を設定し、再利用防止策を講じます。simplejwtでは以下のように設定可能です。
settings.py
|
1 2 3 4 5 6 7 |
from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30), 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), } |
HTTPS必須の理由
認証情報が明文で送信されるため、HTTP通信ではハッキングリスクがあります。必ずHTTPSを使用する必要があります。
認証情報の暗号化技術(AES/RSA)
トークンに機密情報を含めないことが原則です。暗号化が必要な場合は以下の手順を実装します。
- 秘密鍵と公開鍵の管理: RSAでは秘密鍵はサーバー側のみ保持し、公開鍵はクライアントに配布
- 暗号化アルゴリズムの選定: AES-256など強力なアルゴリズムを使用
- 暗号文の保存と検証: 認証情報をデータベースやキャッシュに保存する際は常に暗号化
例: AESによるメッセージ暗号化(Python)
|
1 2 3 4 5 6 7 |
from Crypto.Cipher import AES import base64 key = b'your-secret-key-123' cipher = AES.new(key, AES.MODE_EAX) ciphertext, tag = cipher.encrypt_and_digest(b'sensitive_data') |
カスタム認証の最適化と検証手順
実装後のパフォーマンスチューニングやテストケース設計が重要です。
パフォーマンスチューニングポイント
- 認証処理内でDBクエリを減らす(キャッシュ利用)
- 大規模なユーザー数対応のためのインデックス設定
テストケース設計のコツ
認証失敗、無効トークン、有効トークンなど、以下のパターンをテストする必要があります。
- 正しいトークンでリクエストを送信
- 無効なトークンでのリクエスト
- トークンが存在しない場合の処理
デバッグ時のログ出力方法
認証処理内でデバッグ用のログを出力し、異常時の挙動を確認します。
|
1 2 3 4 |
import logging logger = logging.getLogger(__name__) logger.debug(f"トークン: {token}") |
まとめ
- DRF標準認証メカニズム(Token/Session)の違いと使い分けを理解する
- JWTとカスタムユーザモデル連携の実装手順をマスター
- ベースクラスからカスタム認証ロジックを構築し、適切に例外処理を行う
- 認証情報はHTTPヘッダで送信すること、HTTPS利用が必須であることを確認
- トークンの有効期限管理とセキュリティリスク対策を実装する
- パフォーマンス向上とテストケース設計に注力し、安定した認証処理を構築
DRFでカスタム認証を実装することは、アプリケーションの信頼性を高める重要なステップです。記事のサンプルコードを基にプロジェクトで実装し、カスタム認証の最適化を試してみましょう。