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.
Se även
Även om användarna använder starka lösenord kan angripare kanske avlyssna deras anslutningar. Använd HTTPS 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
för ett User
-objekt är en sträng i detta format:
<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-algoritmen med en SHA256-hash, en mekanism för lösenordsträckning som rekommenderas av NIST. 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
. 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
. För att lagra nya lösenord med en annan algoritm, sätt din föredragna algoritm först i 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
, kommer försök att verifiera det att ge upphov till ValueError
.
Standardvärdet för 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 för att lagra alla lösenord men kommer att stödja kontroll av lösenord som lagras med PBKDF2SHA1, argon2 och 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 är vinnaren av 2015 års Password Hashing Competition, en öppen tävling som anordnas av ett community 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 ä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:
Installera paketet argon2-cffi. Detta kan göras genom att köra
python -m pip install django[argon2]
, vilket är likvärdigt medpython -m pip install argon2-cffi
(tillsammans med eventuella versionskrav från Djangospyproject.toml
).Ändra
PASSWORD_HASHERS
till att listaArgon2PasswordHasher
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.
Använda bcrypt
med Django¶
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:
Installera paketet bcrypt. Detta kan göras genom att köra
python -m pip install django[bcrypt]
, vilket är likvärdigt medpython -m pip install bcrypt
(tillsammans med eventuella versionskrav från Djangospyproject.toml
).Ändra
PASSWORD_HASHERS
till att listaBCryptSHA256PasswordHasher
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.
Det var allt - nu kommer din Django-installation att använda Bcrypt som standardlagringsalgoritm.
Använda scrypt
med Django¶
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 ä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 för mer information.
Gör så här om du vill använda scrypt som standardalgoritm för lagring:
Ändra
PASSWORD_HASHERS
så attScryptPasswordHasher
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.
Observera
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:
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
.Lägg till din nya hasher som den första posten i
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.
Observera
bcrypt rundor
är en logaritmisk arbetsfaktor, t.ex. 12 rundor betyder 2 ** 12
iterationer.
Argon2¶
Argon2 har följande attribut som kan anpassas:
time_cost
styr antalet iterationer inom hashen.memory_cost
styr storleken på det minne som måste användas under beräkningen av hashen.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:
Välj
parallellism
till det antal trådar som du kan avvara för att beräkna hashen.Välj
memory_cost
till det KiB minne som du kan avvara.Justera
time_cost
och mät den tid det tar att hasha ett lösenord. Välj entime_cost
som tar en acceptabel tid för dig. Omtime_cost
inställd på 1 är oacceptabelt långsam, sänkmemory_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 har följande attribut som kan anpassas:
work_factor
styr antalet iterationer inom hashen.block_storlek
parallelism
styr hur många trådar som ska köras parallellt.maxmem
begränsar den maximala storleken på minnet som kan användas under beräkningen av hashen. Standardvärdet är0
, 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 ä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
, 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.
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
¶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
¶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
-inställning:
mysite/settings.py
¶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
tillhandahåller en uppsättning funktioner för att skapa och validera hashade lösenord. Du kan använda dem oberoende av User
-modellen.
- 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()
. Den tar två obligatoriska argument: det lösenord i klartext som ska kontrolleras och det fullständiga värdet på användarens fältpassword
i databasen som ska kontrolleras mot. Den returnerarTrue
om de matchar,False
annars. Alternativt kan du skicka en anropsbaretter
som tar lösenordet och som kommer att anropas när du behöver regenerera det. Du kan också skickapreferred
för att ändra en hashingalgoritm om du inte vill använda standardalgoritmen (första posten i inställningenPASSWORD_HASHERS
). Se Inkluderade hasplar för namnet på algoritmen för varje hasher.
- make_password(password, salt=None, hasher='default')[source]¶
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 för namnet på algoritmen för varje hasher. Om lösenordsargumentet ärNone
returneras ett oanvändbart lösenord (ett lösenord som aldrig kommer att accepteras avcheck_password()
).
- is_password_usable(encoded_password)[source]¶
Returnerar
False
om lösenordet är ett resultat avUser.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
. 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
ä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
och 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.
Observera
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
:
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
.
Inkluderade validerare¶
Django innehåller fyra validerare:
- class MinimumLengthValidator(min_length=8)[source]¶
Verifierar att lösenordet har en minimilängd. Minimilängden kan anpassas med parametern
min_length
.
- class UserAttributeSimilarityValidator(user_attributes=DEFAULT_USER_ATTRIBUTES, max_similarity=0.7)[source]¶
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 avdifflib.SequenceMatcher.quick_ratio()
. Ett värde på 0,1 avvisar lösenord om de inte skiljer sig väsentligt frånuser_attributes
, medan ett värde på 1,0 endast avvisar lösenord som är identiska med ett attributs värde.
- class CommonPasswordValidator(password_list_path=DEFAULT_PASSWORD_LIST_PATH)[source]¶
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.
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.
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)[source]¶
Validerar ett lösenord. Om alla validerare anser att lösenordet är giltigt returneras
None
. Om en eller flera validerare avvisar lösenordet, skapas enValidationError
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)[source]¶
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
kommer lösenordsfältet att markeras som ”dirty” vid anrop avset_password()
som utlöser ett anrop tillpassword_changed()
efter att användaren har sparats.
- password_validators_help_texts(password_validators=None)[source]¶
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 parameternhelp_text
i ett formulärfält.
- get_password_validators(validator_config)[source]¶
Returnerar en uppsättning valideringsobjekt baserat på parametern
validator_config
. Som standard använder alla funktioner de validerare som definieras iAUTH_PASSWORD_VALIDATORS
, men genom att anropa den här funktionen med en alternativ uppsättning validerare och sedan skicka resultatet till parameternpassword_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ånAUTH_PASSWORD_VALIDATORS
används som standard.Strukturen för
validator_config
är identisk med strukturen förAUTH_PASSWORD_VALIDATORS
. Returvärdet för denna funktion kan skickas till parameternpassword_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. ReturnerarNone
om lösenordet är giltigt, eller ger ettValidationError
med ett felmeddelande om lösenordet inte är giltigt. Du måste kunna hantera attuser
ärNone
- om det betyder att din validerare inte kan köras, returneraNone
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
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.