概要
Django REST Frameworkとdjango-axesを使用して、ログイン試行に失敗した場合のアカウントロック(アカウント凍結)機能を実装する方法を説明します!
使用技術
python = "^3.11.2"
Django = "^4.2.7"
djangorestframework = "^3.14.0"
pydantic = "^1.10.7"
gunicorn = "^21.2.0"
django-axes = "^6.1.1"
説明する前の前提
コードの細部やDjango REST Framework自体の説明はあまりしません
また、インポートもとのコードが不要な場合は明記していません
ご了承ください🙇
django-axesとは
Djangoフレームワーク内でログイン試行の監視やアカウントロック、IPアドレスのブラックリスト等の機能を提供してくれる多機能なライブラリです
早速コードを見ていきましょう!
まずは設定から
INSTALLED_APPS = [
# 以下を追加 他は省略
"axes",
]
MIDDLEWARE = [
# 以下を追加 他は省略
"axes.middleware.AxesMiddleware",
]
AUTHENTICATION_BACKENDS = [
# 以下を追加
"axes.backends.AxesBackend",
"django.contrib.auth.backends.ModelBackend",
]
settings.pyにてdjango-axesをアプリに読み込んでもらうように各記述を追記していきましょう
from pydantic import BaseSettings
class AxesVariableSettings(BaseSettings):
"""django-axes関連の環境変数を取得する設定クラス"""
AXES_FAILURE_LIMIT: int = 5
"""ロックされるまでのログイン回数"""
AXES_COOLOFF_TIME: float = 1
"""自動でロックが解除されるまでの時間"""
AXES_LOCKOUT_PARAMETERS: list = ["username"]
"""ロック対象をusernameで判断する"""
AXES_RESET_ON_SUCCESS: bool = True
"""ログインに成功したら失敗回数をリセットする"""
AXES_RESET_COOL_OFF_ON_FAILURE_DURING_LOCKOUT: bool = False
"""Trueの場合、ロックアウト中にログインに失敗した場合、クールオフ期間がリセット"""
例えば上記のように環境変数は設定できます
以下で指定できるオプションを確認できます
from axes.signals import user_locked_out
from django.dispatch import receiver
from rest_framework.exceptions import PermissionDenied
@receiver(user_locked_out)
def axes_signal(*args, **kwargs):
raise PermissionDenied("アカウントは凍結されてるよ。ちょっと待ってね")
ライブラリが提供するuser_locked_out シグナルをキャッチし、そのイベントが発生した際に特定の処理を実行するためのものです
from django.apps import AppConfig
class ApplicationConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "app"
def ready(self):
from common import axes_signal
ready
メソッドは、アプリケーションが起動したときに実行される初期化コードを提供します。この特定の ready
メソッドでは、axes_signal
関数をインポートしています
特に、user_locked_out
シグナルが発生したときに、アカウントが凍結されたことを示すメッセージを含んだ PermissionDenied
例外を発生させます
準備は整いました!!動きを確認してみましょう🔥
アカウントロック状態はaccess_attemptテーブルで管理されています
今は何もレコードがありません
1回ログインに失敗するとレコードが生成されます
failures_since_startが1となっています
5回失敗してみました
これでfailures_since_startが5回となり、先ほど設定した失敗した旨のエラーレスポンスが返却されます
この状態で正しいユーザーID、パスワードでログインしようとしても凍結されているのエラーが返ってきます👍
AXES_COOLOFF_TIMEで指定した時間が経過するか、該当レコードを削除すると
アカウントロックは解除されます
なので、アカウントロック解除機能を実現するには該当のレコードを指定して、削除すれば実装できます
最後に
流れさえ、抑えればスムーズに開発が進められると思います🐰
アカウントロック機能について説明されている記事は少なかったので参考になれば嬉しいです
ぜひ、お試しを!