---
title: "Lösenordshantering i Django"
version: 5.2
locale: sv
source: https://docs.djangoproject.com/sv/5.2/topics/auth/passwords/
canonical: https://djangodocs.dev/sv/5.2/topics/auth/passwords/
---
# Lösenordshantering i Django

Lösenordshantering är något som i allmänhet inte bör uppfinnas på nytt i onödan, och Django strävar efter att tillhandahålla en säker och flexibel uppsättning verktyg för hantering av användarlösenord. Detta dokument beskriver hur Django lagrar lösenord, hur hashningen av lagringen kan konfigureras och några verktyg för att arbeta med hashade lösenord.

> **See also**
>
> Även om användarna använder starka lösenord kan angripare kanske avlyssna deras anslutningar. Använd [HTTPS](/sv/5.2/topics/security/#security-recommendation-ssl) för att undvika att skicka lösenord (eller andra känsliga data) via vanliga HTTP-anslutningar eftersom de är sårbara för lösenordssniffning.

## Hur Django lagrar lösenord

Django tillhandahåller ett flexibelt system för lagring av lösenord och använder PBKDF2 som standard.

Attributet [`password`](/sv/5.2/ref/contrib/auth/#django.contrib.auth.models.User.password) för ett [`User`](/sv/5.2/ref/contrib/auth/#django.contrib.auth.models.User)-objekt är en sträng i detta format:

```text
<algorithm>$<iterations>$<salt>$<hash>
```

Dessa är de komponenter som används för att lagra en användares lösenord, separerade med dollartecknet och består av: hashingalgoritmen, antalet algoritmiterationer (arbetsfaktor), det slumpmässiga saltet och den resulterande lösenordshashen.  Algoritmen är en av ett antal envägs hash- eller lösenordslagringsalgoritmer som Django kan använda, se nedan. Iterationer beskriver hur många gånger algoritmen körs över hashen. Salt är det slumpmässiga frö som används och hashen är resultatet av envägsfunktionen.

Som standard använder Django [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)-algoritmen med en SHA256-hash, en mekanism för lösenordsträckning som rekommenderas av [NIST](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf). Detta bör vara tillräckligt för de flesta användare: det är ganska säkert och kräver enorma mängder datatid för att bryta.

Beroende på dina krav kan du dock välja en annan algoritm eller till och med använda en anpassad algoritm för att matcha din specifika säkerhetssituation. Återigen, de flesta användare ska inte behöva göra det här - om du inte är säker behöver du förmodligen inte göra det.  Om du gör det, läs vidare:

Django väljer vilken algoritm som ska användas genom att konsultera inställningen [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS). Detta är en lista över hashingalgoritmklasser som denna Django-installation stöder.

För att lagra lösenord kommer Django att använda den första hashern i [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS). För att lagra nya lösenord med en annan algoritm, sätt din föredragna algoritm först i [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS).

För att verifiera lösenord kommer Django att hitta den hasher i listan som matchar algoritmnamnet i det lagrade lösenordet. Om ett lagrat lösenord namnger en algoritm som inte finns i [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS), kommer försök att verifiera det att ge upphov till `ValueError`.

Standardvärdet för [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS) är:

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

Detta innebär att Django kommer att använda [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) för att lagra alla lösenord men kommer att stödja kontroll av lösenord som lagras med PBKDF2SHA1, [argon2](https://en.wikipedia.org/wiki/Argon2) och [bcrypt](https://en.wikipedia.org/wiki/Bcrypt).

I de följande avsnitten beskrivs ett par vanliga sätt som avancerade användare kan vilja ändra den här inställningen på.

### Använda Argon2 med Django

[Argon2](https://en.wikipedia.org/wiki/Argon2) är vinnaren av 2015 års [Password Hashing Competition](https://www.password-hashing.net/), en öppen tävling som anordnas av en gemenskap för att välja nästa generations hashingalgoritm. Den är utformad för att inte vara lättare att beräkna på anpassad hårdvara än den är att beräkna på en vanlig CPU. Standardvarianten för Argon2-lösenordshashern är Argon2id.

[Argon2](https://en.wikipedia.org/wiki/Argon2) är inte standard för Django eftersom det kräver ett tredjepartsbibliotek. Tävlingspanelen för lösenordshashing rekommenderar dock omedelbar användning av Argon2 snarare än de andra algoritmerna som stöds av Django.

Gör så här om du vill använda Argon2id som standardalgoritm för lagring:

1. Installera paketet [argon2-cffi](https://pypi.org/project/argon2-cffi/). Detta kan göras genom att köra `python -m pip install django[argon2]`, vilket är likvärdigt med `python -m pip install argon2-cffi` (tillsammans med eventuella versionskrav från Djangos `pyproject.toml`).
2. Ändra [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS) till att lista `Argon2PasswordHasher` först. Det vill säga, i din inställningsfil skulle du skriva:

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

   Behåll och/eller lägg till poster i den här listan om du vill att Django ska [uppgradera lösenord](#password-upgrades).

### Använda `bcrypt` med Django

[Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) är en populär algoritm för lagring av lösenord som är särskilt utformad för långvarig lagring av lösenord. Det är inte den standard som används av Django eftersom det kräver användning av tredjepartsbibliotek, men eftersom många människor kanske vill använda det stöder Django bcrypt med minimal ansträngning.

Gör så här om du vill använda Bcrypt som standardalgoritm för lagring:

1. Installera paketet [bcrypt](https://pypi.org/project/bcrypt/). Detta kan göras genom att köra `python -m pip install django[bcrypt]`, vilket är likvärdigt med `python -m pip install bcrypt` (tillsammans med eventuella versionskrav från Djangos `pyproject.toml`).
2. Ändra [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS) till att lista `BCryptSHA256PasswordHasher` först. Det vill säga, i din inställningsfil skulle du skriva:

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

   Behåll och/eller lägg till poster i den här listan om du vill att Django ska [uppgradera lösenord](#password-upgrades).

Det var allt - nu kommer din Django-installation att använda Bcrypt som standardlagringsalgoritm.

### Använda `scrypt` med Django

[scrypt](https://en.wikipedia.org/wiki/Scrypt) liknar PBKDF2 och bcrypt genom att använda ett bestämt antal iterationer för att sakta ner brute-force-attacker. Men eftersom PBKDF2 och bcrypt inte kräver mycket minne kan angripare med tillräckliga resurser starta storskaliga parallella attacker för att påskynda angreppsprocessen. [scrypt](https://en.wikipedia.org/wiki/Scrypt) är särskilt utformad för att använda mer minne jämfört med andra lösenordsbaserade nyckeldrivningsfunktioner för att begränsa mängden parallellism som en angripare kan använda, se [**RFC 7914**](https://datatracker.ietf.org/doc/html/rfc7914.html) för mer information.

Gör så här om du vill använda [scrypt](https://en.wikipedia.org/wiki/Scrypt) som standardalgoritm för lagring:

1. Ändra [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS) så att `ScryptPasswordHasher` listas först. Det vill säga, i din inställningsfil:

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

   Behåll och/eller lägg till poster i den här listan om du vill att Django ska [uppgradera lösenord](#password-upgrades).

> **Note**
>
> `scrypt` kräver OpenSSL 1.1+.

### Ökning av saltets entropi

De flesta lösenordshashar innehåller ett salt tillsammans med sin lösenordshash för att skydda mot regnbågstabellsattacker. Själva saltet är ett slumpmässigt värde som ökar storleken och därmed kostnaden för regnbågstabellen och är för närvarande inställt på 128 bitar med värdet `salt_entropy` i `BasePasswordHasher`. I takt med att beräknings- och lagringskostnaderna minskar bör detta värde höjas. När du implementerar din egen lösenordshasher kan du åsidosätta detta värde för att använda en önskad entropinivå för dina lösenordshashar. `salt_entropy` mäts i bitar.

> **Detaljer om genomförandet**
>
> På grund av den metod som används för att lagra saltvärden är värdet `salt_entropy` i praktiken ett minimivärde. Till exempel skulle ett värde på 128 ge ett salt som faktiskt innehåller 131 bitar entropi.

### Ökning av arbetsfaktorn

#### PBKDF2 och bcrypt

Algoritmerna PBKDF2 och bcrypt använder ett antal iterationer eller rundor för hashning. Detta gör att angriparna medvetet blir långsammare, vilket försvårar attacker mot hashade lösenord. I takt med att datorkraften ökar måste dock antalet iterationer ökas. Vi har valt en rimlig standard (och kommer att öka den med varje version av Django), men du kanske vill justera den upp eller ner, beroende på dina säkerhetsbehov och tillgänglig processorkraft. För att göra det underklassar du lämplig algoritm och åsidosätter parametern `iterations` (använd parametern `rounds` när du underklassar en bcrypt hasher). Till exempel, för att öka antalet iterationer som används av standard PBKDF2-algoritmen:

1. Skapa en underklass av `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
   ```

   Spara detta någonstans i ditt projekt. Till exempel kan du lägga det i en fil som `myproject/hashers.py`.
2. Lägg till din nya hasher som den första posten i [`PASSWORD_HASHERS`](/sv/5.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",
   ]
   ```

Det var allt - nu kommer din Django-installation att använda fler iterationer när den lagrar lösenord med PBKDF2.

> **Note**
>
> bcrypt `rundor` är en logaritmisk arbetsfaktor, t.ex. 12 rundor betyder `2 ** 12` iterationer.

#### Argon2

Argon2 har följande attribut som kan anpassas:

1. `time_cost` styr antalet iterationer inom hashen.
2. `memory_cost` styr storleken på det minne som måste användas under beräkningen av hashen.
3. `parallelism` styr hur många CPU:er som beräkningen av hashen kan parallelliseras på.

Standardvärdena för dessa attribut är förmodligen bra för dig. Om du tycker att lösenordshashen är för snabb eller för långsam kan du justera den på följande sätt:

1. Välj `parallellism` till det antal trådar som du kan avvara för att beräkna hashen.
2. Välj `memory_cost` till det KiB minne som du kan avvara.
3. Justera `time_cost` och mät den tid det tar att hasha ett lösenord. Välj en `time_cost` som tar en acceptabel tid för dig. Om `time_cost` inställd på 1 är oacceptabelt långsam, sänk `memory_cost`.

> **tolkning av minneskostnad**
>
> Kommandoradsverktyget argon2 och vissa andra bibliotek tolkar parametern `memory_cost` på ett annat sätt än det värde som Django använder. Omvandlingen ges av `memory_cost == 2 ** memory_cost_commandline`.

#### `skryptera`

[scrypt](https://en.wikipedia.org/wiki/Scrypt) har följande attribut som kan anpassas:

1. `work_factor` styr antalet iterationer inom hashen.
2. `block_storlek`
3. `parallelism` styr hur många trådar som ska köras parallellt.
4. `maxmem` begränsar den maximala storleken på minnet som kan användas under beräkningen av hashen. Standardvärdet är `0`, vilket innebär standardbegränsningen från OpenSSL-biblioteket.

Vi har valt rimliga standardvärden, men du kanske vill justera dem uppåt eller nedåt, beroende på dina säkerhetsbehov och tillgänglig processorkraft.

> **Uppskatta minnesanvändning**
>
> Minsta minnesbehov för [scrypt](https://en.wikipedia.org/wiki/Scrypt) är:
>
> ```
> work_factor * 2 * block_size * 64
> ```
>
> så du kan behöva justera `maxmem` när du ändrar värdena `work_factor` eller `block_size`.

### Uppgradering av lösenord

När användare loggar in, om deras lösenord lagras med något annat än den föredragna algoritmen, kommer Django automatiskt att uppgradera algoritmen till den föredragna algoritmen. Detta innebär att gamla installationer av Django automatiskt blir säkrare när användare loggar in, och det innebär också att du kan byta till nya (och bättre) lagringsalgoritmer när de uppfinns.

Django kan dock endast uppgradera lösenord som använder algoritmer som nämns i [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS), så när du uppgraderar till nya system bör du se till att aldrig *ta bort* poster från den här listan. Om du gör det kommer användare som använder algoritmer som inte nämns inte att kunna uppgradera. Hashade lösenord kommer att uppdateras när antalet PBKDF2-iterationer, bcrypt-rundor eller argon2-attribut ökas (eller minskas).

Tänk på att om alla lösenord i din databas inte är kodade i standardalgoritmen för hasharen, kan du vara sårbar för en tidsattack med uppräkning av användare på grund av en skillnad mellan varaktigheten för en inloggningsbegäran för en användare med ett lösenord som är kodat i en icke-standardalgoritm och varaktigheten för en inloggningsbegäran för en icke-existerande användare (som kör standardalgoritmen för hasharen). Du kanske kan mildra detta genom att [uppgradera äldre lösenordshashar](#wrapping-password-hashers).

### Lösenordsuppgradering utan krav på inloggning

Om du har en befintlig databas med en äldre, svag hash, t.ex. MD5, kanske du vill uppgradera dessa hashar själv istället för att vänta på att uppgraderingen ska ske när en användare loggar in (vilket kanske aldrig sker om en användare inte återvänder till din webbplats). I det här fallet kan du använda en ”wrappad” lösenordshash.

I det här exemplet migrerar vi en samling MD5-hashar till att använda PBKDF2(MD5(password)) och lägger till motsvarande lösenordshash för att kontrollera om en användare angav rätt lösenord vid inloggning. Vi antar att vi använder den inbyggda `User`-modellen och att vårt projekt har en `accounts`-app. Du kan ändra mönstret så att det fungerar med vilken algoritm som helst eller med en anpassad användarmodell.

Först ska vi lägga till den anpassade hasharen:

*`konton/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)
```

Datamigreringen kan se ut ungefär som följer:

*`konton/migreringar/0002_migrera_md5_lösenord.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),
    ]
```

Tänk på att denna migrering kommer att ta i storleksordningen flera minuter för flera tusen användare, beroende på hastigheten på din maskinvara.

Slutligen lägger vi till en [`PASSWORD_HASHERS`](/sv/5.2/ref/settings/#std-setting-PASSWORD_HASHERS)-inställning:

*`mysite/settings.py`*

```python
PASSWORD_HASHERS = [
    "django.contrib.auth.hashers.PBKDF2PasswordHasher",
    "accounts.hashers.PBKDF2WrappedMD5PasswordHasher",
]
```

Inkludera alla andra hashrar som din webbplats använder i den här listan.

### Inkluderade hasplar

Den fullständiga listan över hashare som ingår i Django är:

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

De motsvarande algoritmnamnen är:

- `pbkdf2_sha256`
- `pbkdf2_sha1`
- `argon2`
- `bcrypt_sha256`
- `bcrypt`
- `skryptera`
- `md5`

### Skriva din egen haschmaskin

Om du skriver en egen lösenordshash som innehåller en arbetsfaktor, t.ex. ett antal iterationer, bör du implementera metoden `harden_runtime(self, password, encoded)` för att överbrygga körtidsgapet mellan den arbetsfaktor som anges i det `kodade` lösenordet och hasherns standardarbetsfaktor. Detta förhindrar en tidsattack för uppräkning av användare på grund av skillnaden mellan en inloggningsbegäran för en användare med ett lösenord som kodats i ett äldre antal iterationer och en icke-existerande användare (som kör standardhasherns standardantal iterationer).

Om vi tar PBKDF2 som exempel och `encoded` innehåller 20.000 iterationer och hasherns standardvärde för `iterationer` är 30.000, bör metoden köra `password` genom ytterligare 10.000 iterationer av PBKDF2.

Om din hasher inte har en arbetsfaktor, implementera metoden som en no-op (`pass`).

## Manuell hantering av en användares lösenord

Modulen [`django.contrib.auth.hashers`](#module-django.contrib.auth.hashers) tillhandahåller en uppsättning funktioner för att skapa och validera hashade lösenord. Du kan använda dem oberoende av `User`-modellen.

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

#### `acheck_password(password, encoded, asetter=None, preferred='default')`

*Asynkron version*: `acheck_password()`

Om du vill autentisera en användare manuellt genom att jämföra ett lösenord i klartext med det hashade lösenordet i databasen kan du använda bekvämlighetsfunktionen [`check_password()`](#django.contrib.auth.hashers.check_password). Den tar två obligatoriska argument: det lösenord i klartext som ska kontrolleras och det fullständiga värdet på användarens fält `password` i databasen som ska kontrolleras mot. Den returnerar `True` om de matchar, `False` annars. Alternativt kan du skicka en anropsbar `etter` som tar lösenordet och som kommer att anropas när du behöver regenerera det. Du kan också skicka `preferred` för att ändra en hashingalgoritm om du inte vill använda standardalgoritmen (första posten i inställningen `PASSWORD_HASHERS`). Se [Inkluderade hasplar](#auth-included-hashers) för namnet på algoritmen för varje hasher.

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

Skapar ett hashat lösenord i det format som används av denna applikation. Det tar ett obligatoriskt argument: lösenordet i klartext (sträng eller byte). Alternativt kan du ange ett salt och en hash-algoritm som ska användas om du inte vill använda standardvärdena (första posten i inställningen `PASSWORD_HASHERS`). Se [Inkluderade hasplar](#auth-included-hashers) för namnet på algoritmen för varje hasher. Om lösenordsargumentet är `None` returneras ett oanvändbart lösenord (ett lösenord som aldrig kommer att accepteras av [`check_password()`](#django.contrib.auth.hashers.check_password)).

#### `is_password_usable(encoded_password)`

Returnerar `False` om lösenordet är ett resultat av [`User.set_unusable_password()`](/sv/5.2/ref/contrib/auth/#django.contrib.auth.models.User.set_unusable_password).

## Validering av lösenord

Användare väljer ofta dåliga lösenord. För att hjälpa till att mildra detta problem erbjuder Django pluggbar lösenordsvalidering. Du kan konfigurera flera lösenordsvaliderare samtidigt. Några validerare ingår i Django, men du kan också skriva dina egna.

Varje lösenordsvalidator måste tillhandahålla en hjälptext för att förklara kraven för användaren, validera ett givet lösenord och returnera ett felmeddelande om det inte uppfyller kraven, och eventuellt definiera en återuppringning för att meddelas när lösenordet för en användare har ändrats. Validerare kan också ha valfria inställningar för att finjustera deras beteende.

Valideringen styrs av inställningen [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS). Standardvärdet för inställningen är en tom lista, vilket innebär att inga validerare tillämpas. I nya projekt som skapas med standardmallen [`startproject`](/sv/5.2/ref/django-admin/#django-admin-startproject) är en uppsättning validerare aktiverade som standard.

Som standard används validatorer i formulären för att återställa eller ändra lösenord och i hanteringskommandona [`createsuperuser`](/sv/5.2/ref/django-admin/#django-admin-createsuperuser) och [`changepassword`](/sv/5.2/ref/django-admin/#django-admin-changepassword). Validerare tillämpas inte på modellnivå, till exempel i `User.objects.create_user()` och `create_superuser()`, eftersom vi antar att utvecklare, inte användare, interagerar med Django på den nivån och även för att modellvalidering inte automatiskt körs som en del av att skapa modeller.

> **Note**
>
> Lösenordsvalidering kan förhindra att många typer av svaga lösenord används. Det faktum att ett lösenord klarar alla validerare garanterar dock inte att det är ett starkt lösenord. Det finns många faktorer som kan försvaga ett lösenord och som inte ens de mest avancerade lösenordsvalidatorerna kan upptäcka.

### Aktivering av lösenordsvalidering

Lösenordsvalidering konfigureras i inställningen [`AUTH_PASSWORD_VALIDATORS`](/sv/5.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",
    },
]
```

I detta exempel aktiveras alla fyra validerare som ingår:

- `UserAttributeSimilarityValidator`, som kontrollerar likheten mellan lösenordet och en uppsättning attribut för användaren.
- `MinimumLengthValidator`, som kontrollerar om lösenordet uppfyller en minimilängd. Den här valideraren är konfigurerad med ett anpassat alternativ: den kräver nu att den minsta längden är nio tecken, i stället för standardvärdet åtta.
- `CommonPasswordValidator`, som kontrollerar om lösenordet finns med i en lista över vanliga lösenord. Som standard jämförs det med en inkluderad lista med 20 000 vanliga lösenord.
- `NumericPasswordValidator`, som kontrollerar om lösenordet inte är helt numeriskt.

För `UserAttributeSimilarityValidator` och `CommonPasswordValidator` använder vi standardinställningarna i det här exemplet. `NumericPasswordValidator` har inga inställningar.

Hjälptexter och eventuella fel från lösenordsvalidatorer returneras alltid i den ordning de listas i [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS).

### Inkluderade validerare

Django innehåller fyra validerare:

#### `class MinimumLengthValidator(min_length=8)`

Verifierar att lösenordet har en minimilängd. Minimilängden kan anpassas med parametern `min_length`.

#### `get_error_message()`

> **New in Django 5.2**

En hook för att anpassa felmeddelandet `ValidationError`. Standard är `"Det här lösenordet är för kort. Det måste innehålla minst <min_length> tecken."`.

#### `get_help_text()`

En hook för att anpassa validatorns hjälptext. Standard är `"Ditt lösenord måste innehålla minst <min_längd> tecken."`.

#### `class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7)`

Kontrollerar att lösenordet skiljer sig tillräckligt mycket från vissa av användarens attribut.

Parametern `user_attributes` bör vara en iterabel med namn på användarattribut att jämföra med. Om detta argument inte anges används standardvärdet: `'username', 'first_name', 'last_name', 'email'`. Attribut som inte existerar ignoreras.

Den maximalt tillåtna likheten mellan lösenord kan ställas in på en skala från 0,1 till 1,0 med parametern `max_similarity`. Detta jämförs med resultatet av [`difflib.SequenceMatcher.quick_ratio()`](https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.quick_ratio). Ett värde på 0,1 avvisar lösenord om de inte skiljer sig väsentligt från `user_attributes`, medan ett värde på 1,0 endast avvisar lösenord som är identiska med ett attributs värde.

#### `get_error_message()`

> **New in Django 5.2**

En hook för att anpassa felmeddelandet `ValidationError`. Standardvärdet är `"Lösenordet är för likt <user_attribute>."`.

#### `get_help_text()`

En hook för att anpassa validatorns hjälptext. Standard är `"Ditt lösenord får inte vara för likt din övriga personliga information."`.

#### `class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)`

Kontrollerar att lösenordet inte är ett vanligt lösenord. Detta konverterar lösenordet till gemener (för att göra en jämförelse utan skiftlägeskänslighet) och kontrollerar det mot en lista med 20 000 vanliga lösenord som skapats av [Royce Williams](https://gist.github.com/roycewilliams/226886fd01572964e1431ac8afc999ce).

Sökvägen för `password_list_path` kan anges till sökvägen för en anpassad fil med vanliga lösenord. Filen ska innehålla ett lösenord med gemener per rad och kan vara i klartext eller gzippad.

#### `get_error_message()`

> **New in Django 5.2**

En hook för att anpassa felmeddelandet `ValidationError`. Standard är `"Det här lösenordet är för vanligt."`.

#### `get_help_text()`

En hook för att anpassa validatorns hjälptext. Standard är `"Ditt lösenord kan inte vara ett vanligt lösenord."`.

#### `class NumericPasswordValidator`

Kontrollera att lösenordet inte är helt numeriskt.

#### `get_error_message()`

> **New in Django 5.2**

En hook för att anpassa felmeddelandet `ValidationError`. Standard är `"Det här lösenordet är helt numeriskt."`.

#### `get_help_text()`

En hook för att anpassa validatorns hjälptext. Standard är `"Ditt lösenord kan inte vara helt numeriskt."`.

### Integrering av validering

Det finns några funktioner i `django.contrib.auth.password_validation` som du kan anropa från dina egna formulär eller annan kod för att integrera lösenordsvalidering. Detta kan vara användbart om du använder anpassade formulär för lösenordsinställning, eller om du har API-anrop som gör det möjligt att ställa in lösenord, till exempel.

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

Validerar ett lösenord. Om alla validerare anser att lösenordet är giltigt returneras `None`. Om en eller flera validerare avvisar lösenordet, skapas en [`ValidationError`](/sv/5.2/ref/exceptions/#django.core.exceptions.ValidationError) med alla felmeddelanden från validerarna.

Objektet `user` är valfritt: om det inte anges kan det hända att vissa validerare inte kan utföra någon validering och accepterar vilket lösenord som helst.

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

Informerar alla validerare om att lösenordet har ändrats. Detta kan användas av validerare som t.ex. förhindrar återanvändning av lösenord. Detta bör anropas när lösenordet har ändrats på ett framgångsrikt sätt.

För underklasser till [`AbstractBaseUser`](/sv/5.2/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser) kommer lösenordsfältet att markeras som ”dirty” vid anrop av [`set_password()`](/sv/5.2/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser.set_password) som utlöser ett anrop till `password_changed()` efter att användaren har sparats.

#### `password_validators_help_texts(password_validators=None)`

Returnerar en lista med hjälptexter för alla validerare. Dessa förklarar lösenordskraven för användaren.

#### `password_validators_help_text_html(password_validators=None)`

Returnerar en HTML-sträng med alla hjälptexter i en `<ul>`. Detta är användbart när du lägger till lösenordsvalidering i formulär, eftersom du kan skicka utdata direkt till parametern `help_text` i ett formulärfält.

#### `get_password_validators(validator_config)`

Returnerar en uppsättning valideringsobjekt baserat på parametern `validator_config`. Som standard använder alla funktioner de validerare som definieras i [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS), men genom att anropa den här funktionen med en alternativ uppsättning validerare och sedan skicka resultatet till parametern `password_validators` i de andra funktionerna kommer din anpassade uppsättning validerare att användas istället. Detta är användbart när du har en typisk uppsättning validerare som kan användas för de flesta scenarier, men också har en speciell situation som kräver en anpassad uppsättning. Om du alltid använder samma uppsättning validerare behöver du inte använda den här funktionen, eftersom konfigurationen från [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS) används som standard.

Strukturen för `validator_config` är identisk med strukturen för [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS). Returvärdet för denna funktion kan skickas till parametern `password_validators` i de funktioner som listas ovan.

Observera att om lösenordet skickas till någon av dessa funktioner ska det alltid vara lösenordet i klartext - inte ett hashat lösenord.

### Skriva din egen validator

Om Djangos inbyggda validerare inte räcker till kan du skriva dina egna lösenordsvaliderare. Validerare har ett ganska litet gränssnitt. De måste implementera två metoder:

- `validate(self, password, user=None)`: validerar ett lösenord. Returnerar `None` om lösenordet är giltigt, eller ger ett [`ValidationError`](/sv/5.2/ref/exceptions/#django.core.exceptions.ValidationError) med ett felmeddelande om lösenordet inte är giltigt. Du måste kunna hantera att `user` är `None` \- om det betyder att din validerare inte kan köras, returnera `None` för inget fel.
- `get_help_text()`: ger en hjälptext för att förklara kraven för användaren.

Alla objekt i `OPTIONS` i [`AUTH_PASSWORD_VALIDATORS`](/sv/5.2/ref/settings/#std-setting-AUTH_PASSWORD_VALIDATORS) för din validator kommer att skickas till konstruktören. Alla konstruktörens argument bör ha ett standardvärde.

Här är ett grundläggande exempel på en validator, med en valfri inställning:

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

Du kan också implementera `password_changed(password, user=None`), som kommer att anropas efter en lyckad lösenordsändring. Det kan till exempel användas för att förhindra återanvändning av lösenord. Men om du bestämmer dig för att lagra en användares tidigare lösenord bör du aldrig göra det i klartext.
