Pengelolaan sandi di Django

Pengelolaan sandi adalah sesuatu yang harus secara umum tidak dibuat kembali tida perlu, dan Django berusaha menyediakan kumpulan aman dan fleksibel dari alat-alat untuk mengelola sandi pengguna. Dokumen ini menggambarkan bagaimana Django menyimpan sandi, bagaimana campuran penyimpanan dapat dikonfigurasikan, dan beberapa peralatan untuk bekerja dengan sandi dicampur.

Lihat juga

Meskipun pengguna mungkin menggunakan sandi kuat, penyerang mungkin dapat menguping pada hubungan mereka. Gunakan HTTPS untuk menghindari mengirim sandi (atau data sensitif lain apapun) terhadap hubungan HTTP polos karena merekan akan menjadi rentan pada penciuman sandi.

Bagaimana Django menyimpan sandi

Django menyediakan sistem penyimpanan sandi fleksibel dan menggunakan PBKDF2 secara awalan.

Atribut password dari objek User adalah string dalam bentuk ini:

<algorithm>$<iterations>$<salt>$<hash>

Mereka adalah komponen digunakan untuk menyimpan sandi User, dipisahkan oleh karakter dolar dan terdiri dari campuran algoritma, sejumlah perulangan algoritma (faktor kerja), garam acak, dan menghasilkan campuran sandi. Algoritma adalah satu dari sejumlah dari campuran satu-cara atau algoritma penyimpanan sandi Django dapat digunakan, lihat dibawah. Perulangan menggambarkan sejumlah kali algoritma berjalan terhadap campuran. Garam adalah benih acak digunakan dan campuran adalah hasil dari fungsi satu-cara.

Secara awalan, Django menggunakan algoritma PBKDF2 dengan campuran SHA256, sebuah mekanisme perentangan sandi dianjurkan oleh NIST. Ini harus cukup untuk kebanyakan pengguna: itu sangat aman, membutuhkan jumlah besar waktu untuk merusak.

Bagaimapun, tergantung pada persyaratan anda, anda mungkin memilih algoritma berbeda, atau bahkan menggunakan penyesuaian algoritma untuk mencocokkan keadaan keamanan khusus. Kembali, kebanyakan pengguna tidak butuh melakukan ini -- jika anda tidak yakin, anda mungkin tidak. Jika anda melakukan, harap membaca:

Django memilih algoritma untuk digunakan dengan berkonsultasi dengan pengaturan PASSWORD_HASHERS. Ini adalah daftar kelas algoritma hashing yang didukung instalasi Django ini.

Untuk menyimpan kata sandi, Django akan menggunakan hasher pertama di PASSWORD_HASHERS. Untuk menyimpan kata sandi baru dengan algoritma berbeda, tempatkan algoritma pilihan anda terlebih dahulu di PASSWORD_HASHERS.

Untuk memverifikasi kata sandi, Django akan menemukan hasher dalam daftar yang cocok dengan nama algoritma dalam kata sandi tersimpan. Jika kata sandi tersimpan menyebutkan algoritma yang tidak ditemukan di PASSWORD_HASHERS, mencoba memverifikasinya akan memunculkan ValueError.

Nilai awal untuk PASSWORD_HASHERS adalah:

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",
]

Ini berarti bahwa Django akan menggunakan PBKDF2 menyimpan semua sandi tetapi akan mendukung pemeriksaan sandi disimpan dengan PBKDF2SHA1, argon2, dan bcrypt.

Sedikit bagian selanjutnya menggambarkan sepasang cara umum pengguna tingkat lanjut mungkin ingin merubah pengaturan ini.

Menggunakan Argon2 dengan Django

Argon2 adalah pemenang Kompetisi Hashing Kata Sandi 2015, sebuah kompetisi terbuka yang diselenggarakan komunitas untuk memilih algoritma hashing generasi berikutnya. Ini dirancang agar tidak lebih mudah untuk menghitung pada perangkat keras khusus daripada menghitung pada CPU biasa. Varian awalan untuk hasher kata sandi Argon2 adalah Argon2id.

Argon2 bukan awalan untuk Django karena itu membutuhkan pustaka pihak-ketiga. Juri Password Hashing Competition, bagaimanapun, menganjurkan penggunaan segera dari Argon2 daripada algoritma lain didukung oleh Django.

Untuk menggunakan Argon2id sebagai algoritma penyimpanan awalan anda, lakukan hal berikut:

  1. Pasang paket argon2-cffi. Ini dapat dilakukan dengan menjalankan python -m pip install django[argon2], yang setara dengan python -m pip install argon2-cffi (bersama dengan persyaratan versi apa pun dari ``setup.cfg` Django `).

  2. Rubah PASSWORD_HASHERS pada daftar Argon2PasswordHasher pertama. Yaitu, di berkas pengaturan anda, anda telah taruh:

    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",
    ]
    

    Jaga dan/atau tambah masukan apapun di daftar ini jika anda butuh Django untuk upgrade passwords.

Menggunakan bcrypt dengan Django

Bcrypt adalah algoritma penyimpanan sandi terkenal yang khususnya dirancang untuk penyimpanan sandi jangka-panjang. Itu bukan awalan digunakan oleh Django sejak itu membutuhkan menggunakan pustaka pihak-ketiga, tetapi sejak banyak orang mungkin ingin menggunakan itu Django mendukung bcrypt dengan usaha minimal.

Untuk menggunakan Bcrypt sebagai algoritma penyimpanan awalan anda, lakukan berikut:

  1. Pasang paket bcrypt. Ini dapat dilakukan dengan menjalankan python -m pip install django[bcrypt], yang setara dengan python -m pip install bcrypt (bersama dengan persyaratan versi apa pun dari setup.cfg Django) .

  2. Rubah PASSWORD_HASHERS pada daftar BCryptSHA256PasswordHasher pertama. Yaitu, di berkas pengaturan anda, anda telah taruh:

    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",
    ]
    

    Jaga dan/atau tambah masukan apapun di daftar ini jika anda butuh Django untuk upgrade passwords.

Yaitu -- sekarang Django memasang dengan menggunakan Bcrypt sebagai algoritma penyimpanan awalan.

Menggunakan scrypt dengan Django

scrypt mirip dengan PBKDF2 dan bcrypt dalam memanfaatkan sejumlah iterasi untuk memperlambat serangan brute-force. Namun, karena PBKDF2 dan bcrypt tidak membutuhkan banyak memori, penyerang dengan sumber daya yang cukup dapat melancarkan serangan paralel berskala besar untuk mempercepat proses penyerangan. scrypt secara khusus dirancang untuk menggunakan lebih banyak memori dibandingkan dengan fungsi derivasi kunci berbasis kata sandi lainnya untuk membatasi jumlah paralelisme yang dapat digunakan penyerang, lihat RFC 7914 untuk detail lebih lanjut.

Untuk menggunakan scrypt sebagai algoritma penyimpanan default anda, lakukan hal berikut:

  1. Ubah PASSWORD_HASHERS untuk mencantumkan ScryptPasswordHasher terlebih dahulu. Yaitu, di berkas pengaturan Anda

    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",
    ]
    

    Jaga dan/atau tambah masukan apapun di daftar ini jika anda butuh Django untuk upgrade passwords.

Catatan

scrypt membutuhkan OpenSSL 1.1+.

Meningkatkan entropi garam

Sebagian besar hash kata sandi menyertakan garam bersama dengan hash kata sandinya untuk melindungi dari serangan tabel pelangi. Garam itu sendiri adalah nilai acak yang meningkatkan ukuran dan juga biaya tabel pelangi dan saat ini ditetapkan pada 128 bit dengan nilai salt_entropy di BasePasswordHasher. Karena biaya komputasi dan penyimpanan menurun, nilai ini harus dinaikkan. Saat menerapkan hasher kata sandi anda sendiri, anda bebas untuk mengganti nilai ini untuk menggunakan tingkat entropi yang diinginkan untuk hash kata sandi anda. salt_entropy diukur dalam bit.

Rincian penerapan

Karena metode penyimpanan nilai garam, nilai salt_entropy secara efektif merupakan nilai minimum. Misalnya nilai 128 akan memberikan garam yang sebenarnya mengandung 131 bit entropi.

Meningkatkan faktor kerja

PBKDF2 dan bcrypt

Algoritme PBKDF2 dan bcrypt menggunakan sejumlah pengulangan atau putaran hashing. Ini sengaja memperlambat penyerang, membuat serangan terhadap kata sandi yang di-campur menjadi lebih sulit. Namun, dengan meningkatnya daya hitung, jumlah putaran perlu ditingkatkan. Kami telah memilih awalan yang masuk akal (dan akan meningkatkannya dengan setiap terbitan Django), tetapi anda mungkin ingin menyetelnya naik atau turun, tergantung pada kebutuhan keamanan anda dan kekuatan pemrosesan yang tersedia. Untuk melakukannya, anda akan mensubklasifikasikan algoritma yang sesuai dan mengganti parameter iterations (gunakan parameter rounds saat mensubklasifikasikan bcrypt hasher). Misalnya, untuk menambah jumlah pengulangan yang digunakan oleh algoritma awalan PBKDF2:

  1. Buat subkelas dari 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
    

    Simpan ini disuatu tempat di proyek anda. Sebagai contoh, anda mungkin menaruh ini di sebuah berkas seperti myproject/hashers.py.

  2. Tambah pencampur baru anda sebagai masukan pertama di 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",
    ]
    

Itu dia -- sekarang pemasangan Django anda akan menggunakan perulangan lebih ketika itu menyimpan sandi menggunakan PBKDF2.

Catatan

bcrypt rounds adalah faktor kerja logaritmik, mis. 12 putaran berarti pengulangan 2 ** 12.

Argon2

Argon2 memiliki atribut berikut yang dapat disesuaikan:

  1. time_cost mengendalikan sejumlah perulangan dalam campuran.
  2. memory_cost mengendalikan ukuran memori yang harus digunakan selama perhitungan dari campuran.
  3. parallelism mengendalikan berapa banyak CPU perhitungan dari campuran dapat diparalelkan.

Nilai-nilai awalan dari atribut ini mungkin baik untuk anda. Jika anda menentukan bahwa campuran sandi terlalu cepat atau terlalu lambat, anda dapat mengutik itu sebagai berikut:

  1. Pilih parallelism untuk menjadi angka dari thread anda dapat hemat menghitung campuran.
  2. Pilih memory_cost menjadi KiB dari memori anda dapat hemat.
  3. Menyesuaikan time_cost dan ukuran waktu mencampur sebuah sandi yang diambil. Ambil sebuah time_cost yang mengambil sebuah waktu yang dapat diterima untuk anda. Jika time_cost disetel menjadi ` adalah tidak dapat diterima lambat, memory_cost lebih rendah.

tafsiran memory_cost

Kegunaan baris-perintah dan beberapa pustaka lain menafsirkan parameter memory_cost berbeda dari nilai yang Django gunakan. Perubahan yang diberikan oleh memory_cost == 2 ** memory_cost_commandline.

scrypt

scrypt memiliki atribut berikut yang dapat disesuaikan:

  1. work_factor mengontrol jumlah perulangan dalam campuran.
  2. block_size
  3. paralelisme mengontrol berapa banyak antrian yang akan berjalan secara paralel.
  4. maxmem membatasi ukuran maksimum memori yang dapat digunakan selama perhitungan campuran. Awalan ke 0, yang berarti batasan awalan dari pustaka OpenSSL.

Kami telah memilih awalan yang masuk akal, tetapi anda mungkin ingin menaikkan atau menurunkannya, bergantung pada kebutuhan keamanan dan daya pemrosesan yang tersedia.

Memperkirakan penggunaan memori

Persyaratan memori minimum scrypt adalah

work_factor * 2 * block_size * 64

jadi anda mungkin perlu men-tweak maxmem saat mengubah nilai work_factor atau block_size.

Peningkatan sandi

Ketika pengguna masuk, jika sandi mereka disimpan dengan apapun lain dari algoritma yang dipilih, Django akan secara otomatis meningkatkan algoritma ke satu yang dipilih. Ini berarti bahwa pemasangan lama dari Django akan mendapatkan otomatis lebih aman ketika pengguna masuk, dan itu juga berarti bahwa anda dapat berganti ke algoritma pentimpanan (dan lebih baik) baru ketika mereka dibuat.

Namun, Django hanya dapat memutakhirkan kata sandi yang menggunakan algoritma yang disebutkan di PASSWORD_HASHERS, jadi saat Anda memutakhirkan ke sistem baru anda harus memastikan untuk tidak pernah menghapus masukan dari daftar ini. Jika anda melakukannya, pengguna yang menggunakan algoritma yang tidak disebutkan tidak akan dapat meningkatkan versi. Kata sandi campuran akan diperbarui saat menambah (atau mengurangi) jumlah perulangan PBKDF2, putaran bcrypt, atau atribut argon2.

Waspada bahwa jika semua sandi di basisdata anda tidak dikodekan di algoritma pencampur awalan, anda mungkin rentan pada serangan pewaktu pencacahan pengguna karena perbedaan diantara lamanya dari permintaan masuk untuk pengguna dengan sandi terkodekan di algoritma bukan-awalan dan lamanya dari permintaan masuk untuk pengguna tidak ada (yang menjalankan pencampur awalan). Anda mungkin dapat memperbaiki ini dengan upgrading older password hashes.

Meningkatkan sandi tanpa membutuhkan masuk

Jika anda memiliki basisdata yang sudah ada dengan campuran yang lebih lama dan lemah seperti MD5, anda mungkin ingin memutakhirkan sendiri campuran tersebut alih-alih menunggu pemutakhiran terjadi saat pengguna masuk (yang mungkin tidak akan pernah terjadi jika pengguna tidak kembali ke situs anda). Dalam hal ini, anda dapat menggunakan pencampur kata sandi "terbungkus".

Untuk contoh ini, kami akan memigrasi kumpulan campuran MD5 untuk menggunakan PBKDF2(MD5(kata sandi)) dan menambahkan pencampur kata sandi yang sesuai untuk memeriksa apakah pengguna memasukkan kata sandi yang benar saat masuk. Kami menganggap kami menggunakan model User bawaan dan bahwa proyek kami memiliki aplikasi accounts. Anda dapat merubah pola untuk bekerja dengan algoritma apa pun atau dengan model pengguna disesuaikan.

Pertama, kami akan menambah penyesuaian pencampur:

accounts/hashers.py
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)

Perpindahan data mungkin terlihat seperti:

accounts/migrations/0002_migrate_md5_passwords.py
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),
    ]

Waspada bahwa perpindahan ini akan mengambil urutan dari beberapa menit untuk beberapa ribuan pengguna, tergantung pada kecepatan perangkat keras anda.

Akhirya, kami akan menambah sebuah pengaturan PASSWORD_HASHERS:

mysite/settings.py
PASSWORD_HASHERS = [
    "django.contrib.auth.hashers.PBKDF2PasswordHasher",
    "accounts.hashers.PBKDF2WrappedMD5PasswordHasher",
]

Sertakan pencampur lain apapun yang situs anda gunakan di daftar ini.

Disertakan pencampur

Daftar penuh dari pencampur disertakan di Django adalah:

[
    "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",
]

Nama-nama algoritma sesuai adalah:

  • pbkdf2_sha256
  • pbkdf2_sha1
  • argon2
  • bcrypt_sha256
  • bcrypt
  • scrypt
  • md5

Menulis pencampur anda sendiri

Jika anda menulis pencampur sandi anda sendiri yang mengandung faktor kerja seperti sejumlah perulangan, anda harus menerapkan sebuah metode harden_runtime(self, password, encoded) untuk menjembatani celah waktu jalan diantara faktor kerja disokong di sandi encoded dan faktor kerja awalan dari pencampur. Ini mencegah serangan pewaktu pencacahan pengguna pada perbedaan diantara permintaan masuk untuk pengguna baru dengan sandi dikodekan di nomor terlama dari perulangan dan pengguna tidak ada (yang menjalankan nomor awalan pencampur bawaan dari perulangan).

Mengambil PBKDF2 sebagai contoh, jika encoded mengandung 20,000 perputaran dan iterations awalan pencampur adalah 30,000, metode harus menjalankan password melalui perputaran 10,000 lain dari PBKDF2.

Jika pencampur anda tidak mempunyai faktor kerja, terapkan metode sebagai no-op (pass).

Manual mengelola sandi pengguna

Modul django.contrib.auth.hashers menyediakan sekumpulan fungsi untuk membuat dan memvalidasi kata sandi campuran. Anda dapat menggunakannya secara terpisah dari model User.

check_password(password, encoded, setter=None, preferred='default')

Jika anda ingin mengautentikasi pengguna secara manual dengan membandingkan kata sandi teks biasa dengan kata sandi campuran di basisdata, gunakan fungsi kemudahan check_password(). Diperlukan dua argumen wajib: kata sandi teks biasa untuk diperiksa, dan nilai lengkap bidang kata sandi pengguna di basisdatauntuk diperiksa. Ia mengembalikan True jika cocok, False jika tidak. Pilihan, anda dapat melewati setter yang dapat dipanggil yang mengambil kata sandi dan akan dipanggil saat anda perlu membuatnya kembali. Anda juga dapat meneruskan preferred untuk mengubah algoritma pencirian jika anda tidak ingin menggunakan awalan (masukan pertama dari pengaturan PASSWORD_HASHERS). Lihat Disertakan pencampur untuk nama algoritma setiap pencampur.

make_password(password, salt=None, hasher='default')

Membuat sandi campuran dalam bentuk yang digunakan oleh aplikasi ini. Dibutuhkan satu argumen wajib: kata sandi dalam teks biasa (string atau byte). Pilihan, anda dapat memberikan garam dan algoritma pencampur untuk digunakan, jika Anda tidak ingin menggunakan awalan (masukan pertama pengaturan PASSWORD_HASHERS). Lihat Disertakan pencampur untuk nama algoritma setiap hasher. Jika argumen kata sandi adalah None, kata sandi yang tidak dapat digunakan dikembalikan (kata sandi yang tidak akan pernah diterima oleh check_password()).

is_password_usable(encoded_password)

Mengembalikan False jika sandi adalah hasil dari User.set_unusable_password().

Pengesahan sandi

Pengguna sering memilih kata sandi yang buruk. Untuk membantu mengurangi masalah ini, Django menawarkan validasi kata sandi yang dapat dicolokkan. Anda dapat mengonfigurasi beberapa validator kata sandi secara bersamaan. Beberapa validator disertakan dalam Django, tetapi anda juga dapat menulisnya sendiri.

Each password validator must provide a help text to explain the requirements to the user, validate a given password and return an error message if it does not meet the requirements, and optionally define a callback to be notified when the password for a user has been changed. Validators can also have optional settings to fine tune their behavior.

Validasi dikontrol oleh pengaturan AUTH_PASSWORD_VALIDATORS. Awalan untuk pengaturan adalah daftar kosong, yang berarti tidak ada validator yang diterapkan. Dalam proyek baru yang dibuat dengan cetakan awalan startproject, sekumpulan validator diaktifkan secara awalan.

Secara awalan, pengesah digunakan dalam formulir untuk menyetel kembali atau merubah sandi dan di perintah pengelolaan createsuperuser dan changepassword. Pengesah tidak diberlakukan pada tingkat model, sebagai contoh di User.objects.create_user()` dan create_superuser(), karena kami mengaggap bahwa pengembang, bukan pengguna, interaksi dengan Django pada tingkat itu dan juga karena pengesahan model tidak secara otomatis berjalan sebagai bagian dari membuat model.

Catatan

Pengesah sandi dapat mencegah penggunaan dari banyak jenis dari sandi lemah. Bagaimanapun, fakta bahwa sandi melewatkan semua pengesah tidak menjami bahwa itu adalah sandi kuat. Ada banyak faktor yang dapat memperlemah sebuah sandi yang tidak dikenali oleh bahkan pengesah sandi paling tingkat lanjut.

Adakan pengesahan sandi

Pengesahan sandi dikonfigurasikan di pengaturan 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",
    },
]

Contoh ini mengadakan semua empat pengesah disertakan:

  • UserAttributeSimilarityValidator, yang memeriksa kemiripan diantara sandi dan sekumpulan dari atribut dari pengguna.
  • MinimumLengthValidator, yang memeriksa apakah kata sandi memenuhi panjang minimum. Validator ini dikonfigurasi dengan opsi khusus: sekarang membutuhkan panjang minimum sembilan karakter, bukan delapan karakter default.
  • CommonPasswordValidator, yang memeriksa apakah kata sandi muncul dalam daftar kata sandi umum. Secara awalan, ini sebanding dengan daftar 20.000 kata sandi umum yang disertakan.
  • NumericPasswordValidator, yang memeriksa apakah sandi tidak sepenuhnya numerik.

Untuk UserAttributeSimilarityValidator dan CommonPasswordValidator, kami menggunakan pengaturan awalan dalam contoh ini. NumericPasswordValidator tidak memiliki pengaturan.

Teks bantuan dan kesalahan apapun dari pengesah sandi selalu dikembalikan agar mereka didaftarkan di AUTH_PASSWORD_VALIDATORS.

Disertakan pengesah

Django menyertakan empat pengesah:

class MinimumLengthValidator(min_length=8)

Memvalidasi bahwa kata sandi memiliki panjang minimum. Panjang minimum dapat disesuaikan dengan parameter min_length.

class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7)

Memvalidasi bahwa kata sandi cukup berbeda dari atribut tertentu pengguna.

Parameter user_attributes harus berupa sebuah perulangan dari nama-namad dari atribut pengguna untuk dibandingkan. Jika argumen ini tidak disediakan, awalan adalah digunakan: 'username', 'first_name', 'last_name', 'email'. Atribut-atribut yang tidak ada adalah diabaikan.

Kesamaan kata sandi maksimum yang diizinkan dapat diatur pada skala 0,1 hingga 1,0 dengan parameter max_similarity. Ini dibandingkan dengan hasil difflib.SequenceMatcher.quick_ratio(). Nilai 0,1 menolak kata sandi kecuali kata sandi tersebut sangat berbeda dari atribut_pengguna, sedangkan nilai 1,0 hanya menolak kata sandi yang identik dengan nilai atribut.

Changed in Django 2.2.26:

Parameter max_similarity dibatasi pada nilai minimal 0.1.

class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)

Memvalidasi bahwa kata sandi bukan kata sandi umum. Ini mengonversi kata sandi menjadi huruf kecil (untuk melakukan perbandingan case-insensitive) dan memeriksanya dengan daftar 20.000 kata sandi umum yang dibuat oleh Royce Williams.

password_list_path dapat disetel ke jalur dari berkas penyesuaian dari sandi umum. Berkas ini harus mengandung sandi satu huruf kecil per baris dan mungkin berupa teks polos atau gzipped.

Changed in Django 4.2:

Daftar 20.000 kata sandi umum telah diperbarui ke versi terbaru.

class NumericPasswordValidator

Validasi bahwa kata sandi tidak sepenuhnya numerik.

Memadukan pengesahan

Ada sedikit fungsi di django.contrib.auth.password_validation yang anda dapat memanggil dari formulir anda sendiri atau kode lain untuk memadukan pengesahan sandi. Ini dapat berguna jika anda menggunakan penyesuaian formulir untuk pengaturan sandi, atau jika anda mempunyai panggilan API yang mengizinkan sandi disetel, sebagai contoh.

validate_password(password, user=None, password_validators=None)

Mengesahkan sebuah sandi. Jika semua pengesah menemukan sandi sah, mengembalikan None. Jika satu atau lebih pengesah menolak sandi, memunculkan sebuah ValidationError dengan semua pesan-pesan kesalahan dari pengesah.

Obyek user adalah pilihan: jika itu tidak disediakan, beberapa pengesah mungkin tidak dapat melakukan pengesahan apapun dan akan menerima sandi apapun.

password_changed(password, user=None, password_validators=None)

Menginformasikan semua pengesah yang sandi telah berubah. Ini dapat digunakan oleh pengesah seperti satu yang mencegah penggunaan kembali sandi. Ini harus dipanggil sekali sandi telah berhasil dirubah.

Untuk subkelas-subkelas dari AbstractBaseUser, bidang sandi akan ditandai sebagai "dirty" ketika memanggil set_password() yang memicu semua pada password_changed() setelah pengguna disimpan.

password_validators_help_texts(password_validators=None)

Mengembalikan daftar dari teks bantuan dari semua pengesah. Ini menjelaskan persyaratan sandi ke pengguna.

password_validators_help_text_html(password_validators=None)

Mengembalikan sebuah string HTML dengan semua bantuan teks di sebuah <ul>. Ini sangat membantu ketika menambahkan pengesahan pada formulir, ketika anda dapat melewatkan keluaran secara langsung ke parameter help_text dari bidang formulir.

get_password_validators(validator_config)

Mengembalikan sekelompok obyek pengesah berdasarkan pada parameter validator_config. Secara awalan, semua fungsi menggunakan pengesah ditentukan di AUTH_PASSWORD_VALIDATORS, tetapi dengan memanggil fungsi ini dengan alternatif kumpulan dari pengesah dan kemudian melewatkan hasil kedalam parameter password_validators dari fungsi lain, kumpulan penyesuaian anda dari pengesah akan digunakan sebagai gantinya. Ini sangat berguna ketika anda mempunyai kumpulan khusus dari pengesah untuk menggunakan kebanyakan skenario, tetapi juga mempunyai keadaan khusus yang membutuhkan penyesuaian kumpulan. Jika anda selalu menggunakan kumpulan sama dari pengesah, tidak perlu menggunakan fungsi ini, ketika konfigurasi dari AUTH_PASSWORD_VALIDATORS digunakan secara awalan.

Struktur dari validator_config``mirip pada struktur dari :setting:`AUTH_PASSWORD_VALIDATORS`. Nilai kembalian dari fungsi ini dapat dilewatkan kedalam parameter ``password_validators dari fungsi-fungsi terdaftar diatas.

Catat bahwa dimana sandi dilewatkan ke satu dari fungsi-fungsi ini, ini harus selalu sandi teks jelas - bukan sebuah sandi dicampur.

Menulis pengesah anda sendiri

Jika validator bawaan Django tidak cukup, anda dapat menulis validator kata sandi anda sendiri. Validator memiliki antarmuka yang cukup kecil. Mereka harus menerapkan dua metode:

  • validate(self, password, user=None): memvalidasi kata sandi. Kembalikan None jika kata sandi valid, atau naikkan ValidationError dengan pesan kesalahan jika kata sandi tidak valid. Anda harus dapat menangani user menjadi None - jika itu berarti validator anda tidak dapat berjalan, kembalikan None tanpa kesalahan.
  • get_help_text(): menyediakan teks bantuan untuk menjelaskan persyaratan ke pengguna.

Barang apapun di OPTIONS di AUTH_PASSWORD_VALIDATORS untuk pengesah anda akan dilewatkan ke pembangun. Semua argumen pembangun harus memiliki nilai awalan.

Ini adalah contoh dasar dari pengecekan, dengan satu pilihan pengaturan:

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}
        )

Anda dapat juga menerapkan password_changed(password, user=None), yang akan dipanggil setelah perubahan sandi berhasil. Itu dapat digunakan untuk mencegah penggunaan kembali sandi, sebagai contoh. Bagaimanapun, jika anda memutuskan menyimpan sandi pengguna sebelumnya, anda harus tidak pernah melakukannya di pembersihan teks.