Djangoにおけるパスワード管理¶
パスワード管理は一般的に、不必要に再発明されるべきではないものです。Djangoはユーザーのパスワードを管理するための安全で柔軟なツールセットを提供するよう努めています。このドキュメントでは、Djangoがパスワードを保存する方法、ストレージハッシュの設定方法、およびハッシュされたパスワードを扱ういくつかのユーティリティについて説明します。
参考
ユーザーが強力なパスワードを使ったとしても、攻撃者が通信経路上において盗聴をおこなう可能性があります。パスワード (または他の機密データ) がプレーンな HTTP コネクションで送信されないように、 HTTPS を使用してください。なぜなら、HTTP はパスワードスニッフィングに対して脆弱であるからです。
Djangoのパスワード保存方法¶
DjangoはデフォルトでPBKDF2を利用した、柔軟なパスワード保存システムを提供します。
User
オブジェクトの password
属性は、次のような形式の文字列です。
<algorithm>$<iterations>$<salt>$<hash>
これらはユーザーのパスワードを保存するためのコンポーネントで、ハッシュアルゴリズム、アルゴリズムのイテレーション回数(ワークファクター)、ランダムなソルト、そして結果のパスワードハッシュをドル記号($)で区切ったものです。このアルゴリズムは、Djangoが使用できる数多くの一方向ハッシュ、またはパスワード保存アルゴリズム(下記参照)の一つです。イテレーションはハッシュに対してアルゴリズムが実行された回数を表します。ソルトは使用されたランダムシードで、ハッシュは一方向ハッシュ関数の実行結果です。
デフォルトでは、Djangoは NIST が推奨するパスワードストレッチングメカニズムである PBKDF2 アルゴリズムと SHA256 ハッシュを使用します。これはほとんどのユーザーに十分有効なはずです。非常に安全で、クラックするのに膨大な計算時間を必要とします。
ただし、要件に応じて、異なるアルゴリズムを使用することも、一部のセキュリティ状況に合わせてカスタムアルゴリズムを使用することもできます。繰り返しますが、ほとんどのユーザーはこれを行う必要はありません。よくわからない場合、おそらくそうしないほうが良いです。もしそうする場合は、こちらをお読みください:
Django は PASSWORD_HASHERS
設定を参照して、使用するアルゴリズムを選択します。これは、この Django インストールがサポートしているハッシュアルゴリズムクラスのリストです。
パスワードの保存には、 Django は PASSWORD_HASHERS
の最初のハッシャーを使います。別のアルゴリズムで新しいパスワードを保存するには、 PASSWORD_HASHERS
にあなたの好きなアルゴリズムを最初に書いてください。
パスワードの検証のために、 Django は保存されたパスワードのアルゴリズム名と一致するハッ シャーをリストの中から探します。保存されたパスワードが PASSWORD_HASHERS
にないアルゴリズ ム名を持つ場合、それを検証しようとすると ValueError
が発生します。
デフォルトでの PASSWORD_HASHERS
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
"django.contrib.auth.hashers.ScryptPasswordHasher",
]
これは、Djangoは PBKDF2 を使用して全てのパスワードを保存しますが、PBKDF2SHA1、 argon2 、および bcrypt で保存されたパスワードのチェックもサポートすることを意味しています。
次のいくつかのセクションでは、高度なユーザーがこの設定を変更するための一般的な方法について説明します。
Django で Argon2 を使う¶
Argon2 は、次世代ハッシュアルゴリズムを選定するコミュニティ主催のオープンコンペティションである、2015年の Password Hashing Competition の優勝者です。カスタムハードウェアで計算しても、通常のCPUで計算するよりも有利にならないように設計されています。Argon2パスワードハッシュのデフォルトのバリアントはArgon2idです。
Argon2 はサードパーティのライブラリを必要とするため、 Django のデフォルトではありません。しかし、 Password Hashing Competition パネルでは、 Django がサポートしている他のアルゴリズムではなく、 Argon2 をすぐに使うことを推奨しています。
Argon2idをデフォルトのストレージアルゴリズムとして使用するには、以下のようにします:
Install the argon2-cffi package. This can be done by running
python -m pip install django[argon2]
, which is equivalent topython -m pip install argon2-cffi
(along with any version requirement from Django'spyproject.toml
).PASSWORD_HASHERS
を変更して、Argon2PasswordHasher
を最初にリストアップします。つまり、設定ファイルに下記のように書きます:PASSWORD_HASHERS = [ "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", "django.contrib.auth.hashers.ScryptPasswordHasher", ]
Django に パスワードのアップグレード をさせる必要がある場合は、このリストにエントリを残すまたは追加してください。
Django で bcrypt
を使う¶
Bcrypt は一般的なパスワード保存アルゴリズムで、特にパスワードの長期保存用に設計されています。サードパーティのライブラリを使う必要があるため、 Django がデフォルトで使うものではありませんが、多くの人が使いたいでしょうから、 Django は最小限の労力で bcrypt をサポートしています。
Bcrypt をデフォルトのストレージアルゴリズムとして使用するには、以下のようにします:
Install the bcrypt package. This can be done by running
python -m pip install django[bcrypt]
, which is equivalent topython -m pip install bcrypt
(along with any version requirement from Django'spyproject.toml
).PASSWORD_HASHERS
を変更して、BCryptSHA256PasswordHasher
を最初にリストアップします。つまり、設定ファイルに下記のように書きます:PASSWORD_HASHERS = [ "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.ScryptPasswordHasher", ]
Django に パスワードのアップグレード をさせる必要がある場合は、このリストにエントリを残すまたは追加してください。
これで Django はデフォルトのストレージアルゴリズムとして Bcrypt を使うようになります。
Django で scrypt
を使う¶
scrypt は、ブルートフォース攻撃を減速させるために設定されたイテレーション数を利用するという点で、PBKDF2やbcryptと似ています。しかし、PBKDF2とbcryptは多くのメモリを必要としないため、十分なリソースを持つ攻撃者は、攻撃プロセスを高速化するために大規模な並列攻撃を仕掛けることができます。 scrypt は、攻撃者が使用できる並列処理の量を制限するために、他のパスワードベースの鍵導出関数と比較してより多くのメモリを使用するように特別に設計されています。
scrypt をデフォルトのストレージアルゴリズムとして使用するには、以下のようにします:
PASSWORD_HASHERS
を変更して、ScryptPasswordHasher
を最初にリストアップします。つまり、設定ファイルに下記のように書きます:PASSWORD_HASHERS = [ "django.contrib.auth.hashers.ScryptPasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", ]
Django に パスワードのアップグレード をさせる必要がある場合は、このリストにエントリを残すまたは追加してください。
注釈
scrypt
はOpenSSL 1.1+を必要とします。
ソルトのエントロピーを増加させる¶
ほとんどのパスワードハッシュはレインボーテーブル攻撃から守るために、パスワードハッシュと一緒にソルトを含んでいます。ソルトはランダムな値であり、レインボーテーブルのサイズとコストを増加させます。現在は BasePasswordHasher
の salt_entropy
値で128ビットに設定されています。計算機やストレージのコストが下がれば、この値を上げる必要があります。独自のパスワードハッシュを実装する場合、パスワードハッシュに希望するエントロピーレベルを使用するために、この値を自由に上書きできます。 salt_entropy
の単位はビットです。
実装の詳細
ソルト値が保存されるメカニズムにより、 salt_entropy
値は実際には最小値です。たとえば、128という値は実際には131ビットのエントロピーを含むソルトを提供します。
work factor を増やす¶
PBKDF2 と bcrypt¶
PBKDF2 と bcrypt アルゴリズムは、ハッシュ化に何度もイテレート(ラウンド)します。これは意図的に攻撃者の速度を低下させ、ハッシュ化されたパスワードに対する攻撃を困難にします。しかし、計算能力が上がるにつれて、イテレーションの回数を増やす必要があります。私たちは妥当なデフォルト値を選びました(そして Django のリリー スごとに増やす予定です)が、セキュリティの必要性や利用可能な処理能力に応じて、上げたり下げたりすることもできます。そのためには、適切なアルゴリズムをサブクラス化し、 iterations
パラメータをオーバーライドします (bcrypt hasher をサブクラス化するときは rounds
パラメータを使います)。たとえば、デフォルトの PBKDF2 アルゴリズムで使用するイテレーションの回数を増やすには、次のようにします:
django.contrib.auth.hashers.PBKDF2PasswordHasher
のサブクラスを作成します:from django.contrib.auth.hashers import PBKDF2PasswordHasher class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher): """ A subclass of PBKDF2PasswordHasher that uses 100 times more iterations. """ iterations = PBKDF2PasswordHasher.iterations * 100
これをプロジェクトのどこかに保存します。たとえば、
myproject/hashers.py
のようなファイルに保存します。新しいハッシャーを
PASSWORD_HASHERS
の最初のエントリーとして追加します:PASSWORD_HASHERS = [ "myproject.hashers.MyPBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2PasswordHasher", "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher", "django.contrib.auth.hashers.Argon2PasswordHasher", "django.contrib.auth.hashers.BCryptSHA256PasswordHasher", "django.contrib.auth.hashers.ScryptPasswordHasher", ]
これで Django が PBKDF2 を使ってパスワードを保存する際に、より多くのイテレーションを使うようになります。
注釈
bcrypt の rounds
は対数の work factor で、たとえば 12 ラウンドは 2 ** 12
のイテレーションを意味します。
Argon2¶
Argon2には、カスタマイズ可能な以下の属性があります:
time_cost
はハッシュ内のイテレートする回数をコントロールします。memory_cost
は、ハッシュの計算に必要なメモリのサイズをコントロールします。parallelism
はハッシュの計算をいくつのCPUで並列化できるかを制御します。
これらの属性のデフォルト値は、おそらく問題ないでしょう。パスワード・ハッシュが速すぎたり遅すぎたりすると判断した場合は、以下のように微調整できます:
parallelism
は、ハッシュを計算するスレッド数を指定します。memory_cost
には、余裕を持ったメモリのKiBを選択してください。time_cost
を調整し、パスワードのハッシュにかかる時間を測定します。time_cost
は、あなたにとって許容できる時間を選んでください。もしtime_cost
に 1 を指定しても許容できないほど遅い場合は、memory_cost
を下げてください。
memory_cost
の解釈
argon2 コマンドラインユーティリティと他のいくつかのライブラリは、 memory_cost
パラメータを Django が使う値とは異なる解釈をします。変換は memory_cost == 2 ** memory_cost_commandline
で行います。
scrypt
¶
scrypt にはカスタマイズ可能な以下の属性があります:
work_factor
はハッシュ内のイテレートする回数をコントロールします。block_size
parallelism
はいくつのスレッドが並列に実行されるかをコントロールします。maxmem
はハッシュの計算中に使用できるメモリの最大サイズを制限します。デフォルトは0
で、OpenSSL ライブラリによるデフォルトの制限を意味します。
私たちは合理的なデフォルト値を選びましたが、セキュリティのニーズや利用可能な処理能力に応じて、調整することもできます。
メモリ使用量の見積もり
scrypt に必要な最小のメモリサイズは以下の通りです:
work_factor * 2 * block_size * 64
そのため、 work_factor
や block_size
の値を変更する際には maxmem
を調整する必要があるかもしれません。
パスワードのアップグレード¶
ユーザーがログインする際、もしそのパスワードが推奨されるアルゴリズム以外で保存されていた場合、Djangoは自動で推奨されるアルゴリズムへ更新します。つまり、Djangoの古いインストールでも、ユーザーのログイン時に自動的にセキュリティが強化され、新しい(より良い)保存アルゴリズムが開発されるたびに切り替えることができるということです。
ただし、Djangoは PASSWORD_HASHERS
で定義されたアルゴリズムを使用するパスワードしか更新できません。そのため、新しいシステムにアップグレードする際には絶対にこのリストからエントリを「削除」しないでください。そうしないと、定義されてないアルゴリズムを使用するユーザーのパスワードを更新できなくなります。ハッシュされたパスワードは、PBKDF2のイテレーション回数、bcrypt のラウンド数、または argon2 の属性数を増やす (または減らす) と更新されます。
データベース上の全てのパスワードがデフォルトのハッシュアルゴリズムでエンコードされていない場合、デフォルト以外のアルゴリズムでエンコードされたパスワードを持つユーザーと、存在しないユーザー(デフォルトのハッシュアルゴリズムが実行されます)に対するログインリクエストにかかる時間の差に起因する、ユーザー列挙型タイミング攻撃に対して脆弱になる可能性があることに注意してください。 古いパスワードハッシュの更新 によりこれを軽減できます。
ログインを必要としないパスワードアップグレード¶
既存のデータベースが MD5 のような古くて弱いハッシュを使用している場合、ユーザがログインしたときにハッシュのアップグレードが行われるのを待つのではなく、自分でハッシュをアップグレードしたいと思うかもしれません (ユーザがサイトに戻ってこない場合は、アップグレードが行われないかもしれません)。この場合、「ラップ」パスワードハッシュを使用できます。
この例では、PBKDF2(MD5(password)) を使用するように MD5 ハッシュのコレクションをマイグレーションし、ユーザがログイン時に正しいパスワードを入力したかどうかをチェックするために、対応するパスワードハッシュを追加します。組み込みの User
モデルを使用しており、プロジェクトには accounts
アプリがあると仮定します。このパターンをカスタマイズすることで、任意のアルゴリズムやカスタムユーザモデルで動作させることができます。
まず、独自のハッシャーを追加します:
from django.contrib.auth.hashers import (
PBKDF2PasswordHasher,
MD5PasswordHasher,
)
class PBKDF2WrappedMD5PasswordHasher(PBKDF2PasswordHasher):
algorithm = "pbkdf2_wrapped_md5"
def encode_md5_hash(self, md5_hash, salt, iterations=None):
return super().encode(md5_hash, salt, iterations)
def encode(self, password, salt, iterations=None):
_, _, md5_hash = MD5PasswordHasher().encode(password, salt).split("$", 2)
return self.encode_md5_hash(md5_hash, salt, iterations)
データマイグレーションは次のようになります:
from django.db import migrations
from ..hashers import PBKDF2WrappedMD5PasswordHasher
def forwards_func(apps, schema_editor):
User = apps.get_model("auth", "User")
users = User.objects.filter(password__startswith="md5$")
hasher = PBKDF2WrappedMD5PasswordHasher()
for user in users:
algorithm, salt, md5_hash = user.password.split("$", 2)
user.password = hasher.encode_md5_hash(md5_hash, salt)
user.save(update_fields=["password"])
class Migration(migrations.Migration):
dependencies = [
("accounts", "0001_initial"),
# replace this with the latest migration in contrib.auth
("auth", "####_migration_name"),
]
operations = [
migrations.RunPython(forwards_func),
]
このマイグレーションには、ハードウェアの速度にもよりますが、数千人のユーザーで数分かかることに注意してください。
最後に PASSWORD_HASHERS
設定を追加します:
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"accounts.hashers.PBKDF2WrappedMD5PasswordHasher",
]
あなたのサイトが使用している他のハッシャーもこのリストに含めてください。
Django に含まれるハッシャー¶
Django に含まれるハッシャーの全リストは以下の通りです:
[
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
"django.contrib.auth.hashers.BCryptPasswordHasher",
"django.contrib.auth.hashers.ScryptPasswordHasher",
"django.contrib.auth.hashers.MD5PasswordHasher",
]
対応するアルゴリズム名は以下の通りです:
pbkdf2_sha256
pbkdf2_sha1
argon2
bcrypt_sha256
bcrypt
scrypt
md5
独自のハッシャーを書く¶
イテレーション回数のようなワークファクターを含む独自のパスワードハッシャーを書く場合は、 harden_runtime(self, password, encoded)
メソッドを実装して、 エンコードされた
パスワードに指定されたワークファクターとハッシャーのデフォルトのワークファクターとの間のランタイムギャップを埋める必要があります。これにより、古いイテレーション数でエンコードされたパスワードを持つユーザーと存在しないユーザー(デフォルトのハッシャーのデフォルトのイテレーション数で実行される)のログイン要求の違いによるユーザー列挙タイミング攻撃を防ぐことができます。
PBKDF2 を例にとると、 encoded
が 20,000 回のイテレーションを含み、ハッシャーのデフォルトの iterations
が 30,000 回である場合、このメソッドは password
を PBKDF2 のさらに 10,000 回のイテレーションに通す必要があります。
もしあなたのハッシャーがワークファクターを持っていない場合は、このメソッドを何もしない操作 (pass
) として実装してください。
ユーザーのパスワードを手動で管理する¶
django.contrib.auth.hashers
モジュールは、ハッシュ化されたパスワードを作成・検証するための関数群を提供します。これらは User
モデルとは独立して使用できます。
- acheck_password(password, encoded, asetter=None, preferred='default')¶
非同期バージョン:
acheck_password()
もしプレーンテキストのパスワードとデータベースのハッシュ化されたパスワードを比較して手動でユーザーを認証したい場合は、
check_password()
という便利な関数を使用してください。この関数は2つの必須引数を取ります。チェックするプレーンテキストのパスワードと、照合するデータベースのpassword
フィールドの完全な値です。これらが一致すればTrue
を返し、一致しなければFalse
を返します。オプションとして、呼び出し可能なsetter
を渡すことができます。このsetter
はパスワードを受け取り、再生成の必要がある際に呼び出されます。また、デフォルトのハッシュアルゴリズム (PASSWORD_HASHERS
設定の最初のエントリ) を使用したくない場合は、preferred
を渡せばハッシュアルゴリズムを変更できます。各ハッシャーのアルゴリズム名については Django に含まれるハッシャー を参照してください。Changed in Django 5.0:acheck_password()
メソッドが追加されました。
- make_password(password, salt=None, hasher='default')[ソース]¶
このアプリケーションで使用する形式でハッシュ化されたパスワードを作成します。必須引数は1つで、プレーンテキスト(文字列またはバイト)のパスワードです。オプションとして、デフォルトを使用したくない場合に使用するソルトとハッシュアルゴリズムを指定できます (
PASSWORD_HASHERS
設定の最初のエントリ)。各ハッシャーのアルゴリズム名については Django に含まれるハッシャー を参照してください。password 引数にNone
を指定すると、使用できないパスワードが返されます (check_password()
では決して受け付けられません)。
- is_password_usable(encoded_password)[ソース]¶
パスワードが
User.set_unusable_password()
の結果の場合はFalse
を返します。
パスワードの妥当性検証¶
ユーザーは、良くないパスワードを選択することがあります。この問題を軽減するために、Djangoはプラガブルなパスワードの妥当性検証を提供しています。複数のパスワードの妥当性検証を同時に設定できます。いくつかのバリデータは Django に含まれていますが、自分で書くこともできます。
各パスワードのバリデータは、ユーザーに要件の説明文を与え、指定されたパスワードの妥当性検証を行い、要件を満たしていない場合はエラーメッセージを返し、オプションでユーザのパスワードが変更されたときに通知するコールバックを定義します。バリデータは、動作を細かく指定するためのオプション設定を持つこともできます。
妥当性検証は AUTH_PASSWORD_VALIDATORS
の設定で管理されます。設定のデフォルトは、空のリストになってます。これは、ひとつもバリデータが適用されていないことを意味しています。 startproject
を使用して作られた新しいプロジェクトでは、バリデータのセットはデフォルトで有効になっています。
デフォルトでは、バリデータはパスワードをリセットまたは変更するフォームと createsuperuser
と changepassword
管理コマンドで使用されます。たとえば、 User.objects.create_user()
や create_superuser()
のようなモデルレベルではバリデータは適用されません。なぜなら、このレベルで Django とやりとりするのはユーザ ではなく開発者であると想定しているからであり、また、モデルのバリデーションがモデル作成の一環として自動的に実行されるわけではないからです。
注釈
パスワードの妥当性検証は多くの脆弱なパスワードの形式が使用されることを防ぎます。しかしながら、パスワードが全てのバリデータを通過するという事実は、強力なパスワードであることを保証するわけではありません。最も先進的なパスワードのバリデータでさえ検出できない、パスワードを弱めうる多くの要素があります。
パスワードの妥当性検証を有効にする¶
パスワードの妥当性検証は AUTH_PASSWORD_VALIDATORS
で構成されます:
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {
"min_length": 9,
},
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
本例では組み込みの4つ全てのバリデータを有効化します。
UserAttributeSimilarityValidator
は、パスワードとユーザの属性との類似性をチェックします。MinimumLengthValidator
は、パスワードが最小の長さを満たしているかをチェックします。このバリデータはカスタムオプションで構成されます。現在の設定では、最小長さは、デフォルトの8文字ではなく、9文字になっています。CommonPasswordValidator
は、一般的なパスワードのリストにそのパスワードが入っていないかをチェックします。デフォルトでは、組み込まれた20,000個のパスワードのリストと比較します。NumericPasswordValidator
は、パスワードが全体的に数値ではないかをチェックします。
UserAttributeSimilarityValidator
と CommonPasswordValidator
については、たとえばこの例ではデフォルトの設定を使用しています。 NumericPasswordValidator
には設定はありません。
パスワードバリデーションのヘルプテキストとエラーは、常に AUTH_PASSWORD_VALIDATORS
に記載されているソート順に返されます。
Django に含まれるバリデータ¶
Django には 4 つのバリデータがあります:
- class MinimumLengthValidator(min_length=8)[ソース]¶
パスワードが最小限の長さであることを検証します。最小の長さは
min_length
パラメータでカスタマイズできます。
- class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7)[ソース]¶
パスワードがユーザの特定の属性と十分に異なることを検証します。
パラメータ
user_attributes
は、比較するユーザー属性の名前のイテラブルでなければなりません。この引数が指定されない場合、デフォルトが使用されます。'username', 'first_name', 'last_name', 'email'
です。存在しない属性は無視されます。パスワードの最大類似度は
max_similarity
パラメータで 0.1 から 1.0 の範囲で指定できます。これはdifflib.SequenceMatcher.quick_ratio()
の結果と比較されます。0.1の値を指定すると、user_attributes
と大幅に異なるパスワード以外は拒否され、1.0の値を指定すると、属性の値と同じパスワードのみが拒否されます。
- class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)[ソース]¶
パスワードが一般的なパスワードでないことを検証します。これはパスワードを小文字に変換し(大文字小文字を区別しない比較を行うため)、 Royce Williams によって作成された20,000の一般的なパスワードのリストと照合します。
password_list_path
には一般的なパスワードのカスタムファイルのパスを指定できます。このファイルには1行につき1つの小文字のパスワードが含まれている必要があり、プレーンテキストまたはgzip圧縮されている必要があります。
バリデーションの統合¶
django.contrib.auth.password_validation
には、独自のフォームや他のコードから呼び出して パスワード認証を統合できる関数がいくつかあります。これは、たとえばパスワードの設定にカスタムフォームを使ったり、 パスワードの設定を許可する API 呼び出しがある場合に便利です。
- validate_password(password, user=None, password_validators=None)[ソース]¶
パスワードを検証します。すべてのバリデータがパスワードを有効と判定した場合、
None
を返します。1つ以上のバリデータがパスワードを拒否した場合、バリデータからのすべてのエラーメッセージと共にValidationError
を発生させます。もし
user
オブジェクトを指定しなかった場合、バリデータによってはバリデーションを実行できず、任意のパスワードを受け取ってしまう可能性があります。
- password_changed(password, user=None, password_validators=None)[ソース]¶
パスワードが変更されたことをすべてのバリデータに通知します。これは、パスワードの再利用を防止するバリデータなどで使用します。パスワードの変更に成功したら、これを呼び出さなければなりません。
AbstractBaseUser
のサブクラスでは、パスワードフィールドはset_password()
を呼び出すと "dirty" としてマークされ、ユーザが保存された後にpassword_changed()
が呼び出されます。
- password_validators_help_texts(password_validators=None)[ソース]¶
すべてのバリデータのヘルプテキストの一覧を返します。これらは、パスワードの条件をユーザに説明するものです。
- password_validators_help_text_html(password_validators=None)¶
すべてのヘルプテキストを
<ul>
で囲んだ HTML 文字列を返します。これはフォームにパスワードバリデーションを追加する際に便利です。フォームフィールドのhelp_text
パラメータに直接出力を渡すことができるからです。
- get_password_validators(validator_config)[ソース]¶
パラメータ
validator_config
に基づいてバリデータオブジェクトのセットを返します。デフォルトでは、すべての関数はAUTH_PASSWORD_VALIDATORS
で定義されたバリデータを使用しますが、この関数を別のバリデータセットで呼び出して、その結果を他の関数のpassword_validators
パラメータに渡すことで、カスタムバリデータセットを代わりに使用できます。これは、たいていの場面で使用する典型的なバリデータセットがありながら、 特別な場面で独自のバリデータセットが必要になる場合に便利です。常に同じバリデータを使う場合は、この関数を使う必要はありません。AUTH_PASSWORD_VALIDATORS
の設定がデフォルトで使われるからです。validator_config
の構造はAUTH_PASSWORD_VALIDATORS
の構造と同じです。この関数の戻り値は上記の関数のpassword_validators
パラメータに渡すことができます。
これらの関数にパスワードが渡される場合は、ハッシュ化されたパスワードではなく、常に平文のパスワードでなければならないことに注意してください。
独自のバリデータを書く¶
Django の組み込みバリデータでは不十分な場合、自分でパスワードバリデータ を書くことができます。バリデータはとても小さなインタフェースを持っています。2 つのメソッドを実装しなければなりません:
validate(self, password, user=None)
: パスワードを検証します。パスワードが有効な場合はNone
を返し、パスワードが無効な場合はエラーメッセージと共にValidationError
を発生させます。もしuser
がNone
であった場合、バリデータが実行できないので、None
を返してエラーにならないようにしてください。get_help_text()
: ユーザに要件を説明するためのヘルプテキストを提供します。
バリデータの AUTH_PASSWORD_VALIDATORS
の OPTIONS
にあるすべての項目がコンストラクタに渡されます。コンストラクタの引数にはデフォルト値を指定します。
以下は、1つのオプション設定を持つ基本的なバリデータの例です。
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
class MinimumLengthValidator:
def __init__(self, min_length=8):
self.min_length = min_length
def validate(self, password, user=None):
if len(password) < self.min_length:
raise ValidationError(
_("This password must contain at least %(min_length)d characters."),
code="password_too_short",
params={"min_length": self.min_length},
)
def get_help_text(self):
return _(
"Your password must contain at least %(min_length)d characters."
% {"min_length": self.min_length}
)
パスワードの変更が成功した後に呼び出される password_changed(password, user=None
) を実装することもできます。これはたとえばパスワードの再利用を防ぐために使用できます。しかし、ユーザーの以前のパスワードを保存することにした場合、決して平文で保存してはいけません。