[Django] ユーザー認証でパスワードに大文字小文字数字を含むよう強制する

Webサービスでよくある「パスワードには大文字小文字数字を含むようにしてください。」を実装する方法をご紹介します。

大文字小文字数字を含むように強制する

まずは、条件を満たしているかを判定するVaridatorクラスを作成します。

# yourapp/password_validation.py
from string import ascii_uppercase, ascii_lowercase, digits

from django.core.exceptions import ValidationError


def contain_any(target, condition_list):
    return any([i in target for i in condition_list])

class CustomValidator:
    message = "パスワードは(大小英字、数字)全てを組み合わせて設定してください。"
    def validate(self, password, user=None):
        if not all([contain_any(password, ascii_lowercase),
                    contain_any(password, ascii_uppercase),
                    contain_any(password, digits)]):
            raise ValidationError(self.message)
    def get_help_text(self):
        return self.message

これをsettings.pyAUTH_PASSWORD_VALIDATORSに追記します。

AUTH_PASSWORD_VALIDATORS = [
    ...
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'yourapp.password_validation.CustomValidator', # 追記
    },
]

以上でユーザーを作成するときのパスワードに大文字小文字数字を含むように強制できます。

メソッドの条件を変えれば他にも色々な制限がかけられます。

蛇足

これ以下に書くことは筆者の個人的な感想であり暗号学、確率論に基づく話はしておりません。
一般のユーザーに対してはパスワードを強固にすればするほど(英数大文字小文字記号を含めるようにしろみたいなパスワードは)どこかにメモを取ることになってそこからパスワードが漏洩する事故が多発するような気がしているのであまり好きではありません。最低文字数の制限だけでいいような… まあ、パスワードマネージャーを使えっていう話ではありますが。