---
title: "Pengelolaan sandi di Django"
version: 4.2
locale: id
source: https://docs.djangoproject.com/id/4.2/topics/auth/passwords/
canonical: https://djangodocs.dev/id/4.2/topics/auth/passwords/
---
# 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.

> **See also**
>
> Meskipun pengguna mungkin menggunakan sandi kuat, penyerang mungkin dapat menguping pada hubungan mereka. Gunakan [HTTPS](/id/4.2/topics/security/#security-recommendation-ssl) 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`](/id/4.2/ref/contrib/auth/#django.contrib.auth.models.User.password) dari objek [`User`](/id/4.2/ref/contrib/auth/#django.contrib.auth.models.User) adalah string dalam bentuk ini:

```text
<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](https://en.wikipedia.org/wiki/PBKDF2) dengan campuran SHA256, sebuah mekanisme perentangan sandi dianjurkan oleh [NIST](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf). 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`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/settings/#std-setting-PASSWORD_HASHERS). Untuk menyimpan kata sandi baru dengan algoritma berbeda, tempatkan algoritma pilihan anda terlebih dahulu di [`PASSWORD_HASHERS`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/settings/#std-setting-PASSWORD_HASHERS), mencoba memverifikasinya akan memunculkan `ValueError`.

Nilai awal untuk [`PASSWORD_HASHERS`](/id/4.2/ref/settings/#std-setting-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](https://en.wikipedia.org/wiki/PBKDF2) menyimpan semua sandi tetapi akan mendukung pemeriksaan sandi disimpan dengan PBKDF2SHA1, [argon2](https://en.wikipedia.org/wiki/Argon2), dan [bcrypt](https://en.wikipedia.org/wiki/Bcrypt).

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

### Menggunakan Argon2 dengan Django

[Argon2](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/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. Install the [argon2-cffi](https://pypi.org/project/argon2-cffi/) package. This can be done by running
   `python -m pip install django[argon2]`, which is equivalent to
   `python -m pip install argon2-cffi` (along with any version requirement
   from Django's `pyproject.toml`).
2. Rubah [`PASSWORD_HASHERS`](/id/4.2/ref/settings/#std-setting-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](#password-upgrades).

### Menggunakan `bcrypt` dengan Django

[Bcrypt](https://en.wikipedia.org/wiki/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. Install the [bcrypt](https://pypi.org/project/bcrypt/) package. This can be done by running
   `python -m pip install django[bcrypt]`, which is equivalent to
   `python -m pip install bcrypt` (along with any version requirement from
   Django's `pyproject.toml`).
2. Rubah [`PASSWORD_HASHERS`](/id/4.2/ref/settings/#std-setting-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](#password-upgrades).

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

### Menggunakan `scrypt` dengan Django

[scrypt](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/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**](https://datatracker.ietf.org/doc/html/rfc7914.html) untuk detail lebih lanjut.

Untuk menggunakan [scrypt](https://en.wikipedia.org/wiki/Scrypt) sebagai algoritma penyimpanan default anda, lakukan hal berikut:

1. Ubah [`PASSWORD_HASHERS`](/id/4.2/ref/settings/#std-setting-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](#password-upgrades).

> **Note**
>
> `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`](/id/4.2/ref/settings/#std-setting-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.

> **Note**
>
> 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](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/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`](/id/4.2/ref/settings/#std-setting-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](#wrapping-password-hashers).

### 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`*

```python
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`*

```python
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`](/id/4.2/ref/settings/#std-setting-PASSWORD_HASHERS):

*`mysite/settings.py`*

```python
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`](#module-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()`](#django.contrib.auth.hashers.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](#auth-included-hashers) 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](#auth-included-hashers) 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()`](#django.contrib.auth.hashers.check_password)).

#### `is_password_usable(encoded_password)`

Mengembalikan `False` jika sandi adalah hasil dari [`User.set_unusable_password()`](/id/4.2/ref/contrib/auth/#django.contrib.auth.models.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`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/django-admin/#django-admin-startproject), sekumpulan validator diaktifkan secara awalan.

Secara awalan, pengesah digunakan dalam formulir untuk menyetel kembali atau merubah sandi dan di perintah pengelolaan [`createsuperuser`](/id/4.2/ref/django-admin/#django-admin-createsuperuser) dan [`changepassword`](/id/4.2/ref/django-admin/#django-admin-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.

> **Note**
>
> 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`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/settings/#std-setting-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()`](https://docs.python.org/3/library/difflib.html#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](https://Gist.github.com/roycewilliams/226886fd01572964e1431ac8afc999ce).

`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`](/id/4.2/ref/exceptions/#django.core.exceptions.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`](/id/4.2/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser), bidang sandi akan ditandai sebagai "dirty" ketika memanggil [`set_password()`](/id/4.2/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser.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`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/settings/#std-setting-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`](/id/4.2/ref/exceptions/#django.core.exceptions.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`](/id/4.2/ref/settings/#std-setting-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.
