Repere Django: Modele de utilizator și autentificare (Partea 1)
Publicat: 2022-03-10Există două tipuri de site-uri web: statice și dinamice. Django este un cadru pentru dezvoltarea site-urilor web dinamice. În timp ce un site web static este unul care prezintă doar informații, nu există nicio interacțiune (dincolo de simple cereri de pagină) care să fie înregistrată pe un server. Într-un site web static, serverul trimite HTML, CSS și JavaScript unui client și atât. Mai multe capabilități necesită un site web dinamic, unde serverul stochează informații și răspunde la interacțiunea utilizatorului dincolo de doar difuzarea paginilor. Un motiv major pentru a dezvolta un site dinamic este autentificarea utilizatorilor și restricționarea conținutului.
Scrierea, implementarea și administrarea unui site web static este cu un ordin de mărime mai ușor, mai ieftin și mai sigur decât un site dinamic. Astfel, ar trebui să creați un site web dinamic numai dacă capacitățile suplimentare ale paradigmei dinamice sunt necesare pentru proiectul dvs. Django simplifică și eficientizează procesul de creare a unui site dinamic cu componentele sale încorporate. Fiind una dintre componentele principale ale unei aplicații web dinamice, obiectul „cont de utilizator”, precum roata, este tentant să se reinventeze, dar forma standard este potrivită pentru majoritatea utilizărilor. Django oferă un model de utilizator puternic, iar în acest articol vom prezenta cel mai bun mod de a oferi fluxuri de autentificare sigure și intuitive.
Alte părți din serie:
- Repere Django: Șabloanele salvează linii (Partea a 2-a)
- Repere Django: modele, administrator și valorificarea bazei de date relaționale (partea 3)
- Repere Django: dispute active statice și fișiere media (partea a 4-a)
Se instalează
Dacă doriți să vă creați propria aplicație Django pentru a experimenta conceptele din acest articol, puteți crea un director (și de preferință un mediu virtual) și apoi executați următoarele comenzi:
pip install django django-admin startproject PROJECTNAME cd PROJECTNAME python manage.py startapp APPNAME python manage.py migrate python manage.py runserver
Dacă sunteți în căutarea unei explicații despre crearea primului dvs. proiect Django, site-ul propriu al Django vă oferă unul grozav. În acest articol, nu folosim un proiect exemplu, dar conceptele discutate se vor aplica aproape tuturor aplicațiilor Django.
Model standard de utilizator
În principiu, conceptul de cont de utilizator există din două motive: controlul accesului și starea personalizată a aplicației. Controlul accesului este ideea că resursele unui sistem sunt disponibile doar pentru unii utilizatori. Starea personalizată depinde în mare măsură de scopul aplicației, dar poate include setări, date sau orice alte înregistrări specifice unui utilizator individual. Modelul Django Stock User
oferă abordări sensibile pentru ambele cazuri de utilizare.
Inițial, există două tipuri de utilizatori într-o aplicație Django: conturi de superutilizator și utilizatori obișnuiți. Superutilizatorii au toate atributele și privilegiile conturilor obișnuite, dar au și acces la panoul de administrare Django, o aplicație puternică pe care o vom explora în detaliu într-un articol viitor. În esență, superutilizatorii pot crea, edita sau șterge orice date din aplicație, inclusiv alte conturi de utilizator.
În principiu, conceptul de cont de utilizator există din două motive: controlul accesului și starea personalizată a aplicației.
„
Pentru a crea un superutilizator în propria aplicație Django, rulați:
python manage.py createsuperuser
Celălalt beneficiu al unui cont de utilizator este stocarea datelor personalizate în baza de date. În mod implicit, Django necesită doar un nume de utilizator și o parolă, dar oferă câmpuri opționale pentru ca utilizatorii să își introducă numele, numele și adresa de e-mail. Puteți citi o referință completă a modelului pe site-ul web Django. Vom discuta despre extinderea acestui model mai jos.
Securitate și fiabilitate
Django include middleware substanțial de gestionare a parolelor cu modelul utilizatorului. Parolele de utilizator trebuie să aibă cel puțin 8 caractere, nu în întregime numere, să nu se potrivească prea mult cu numele de utilizator și să nu figureze pe o listă cu cele mai comune 20.000 de parole. Formularele de stoc Django validează aceste cerințe. Când o parolă este trimisă către server, aceasta este criptată înainte de a fi stocată, utilizând implicit algoritmul PBKDF2 cu un hash SHA256. În general, sistemul de parole implicit oferă securitate robustă, fără niciun efort din partea dezvoltatorului. Dacă nu aveți o experiență specifică și un motiv convingător pentru a schimba modul în care parolele sunt gestionate în aplicația dvs., nu modificați acest comportament.
Un alt încorporat convenabil este cerința ca numele de utilizator să fie unice. Dacă vă gândiți bine, dacă ar exista doi utilizatori cu numele de utilizator „djangofan1” și serverul ar primi o solicitare de autentificare pentru acel nume de utilizator, nu ar ști care utilizator încearcă să acceseze aplicația. Din păcate pentru ei, al doilea utilizator care încearcă să se înregistreze cu „djangofan1” va trebui să aleagă un alt nume, poate „djangofan2”. Această constrângere de unicitate este impusă la nivelul bazei de date, dar este din nou verificată de formularele oferite de Django.
În sfârșit, o notă despre ștergerea utilizatorilor. Deși ștergerea utilizatorilor este o posibilitate, majoritatea aplicațiilor complexe vor avea un număr de resurse legate de fiecare cont de utilizator. Dacă doriți să ștergeți efectiv un utilizator fără a elimina acele obiecte atașate, setați în schimb câmpul is_active
al utilizatorului la false. Apoi, acele alte resurse rămân asociate contului în loc să fie șterse ele însele, iar contul de utilizator poate fi reactivat în orice moment de către un superutilizator. Rețineți că acest lucru nu eliberează numele de utilizator, dar setarea contului ca inactiv împreună cu schimbarea numelui de utilizator la o valoare unică, aleatorie, ar putea obține același efect. În cele din urmă, dacă politicile site-ului dvs. sau legislația locală aplicabilă impun ca conturile de utilizator să fie complet șterse, abordarea is_active
nu va fi suficientă.
Dacă nu aveți o experiență specifică și un motiv convingător pentru a schimba modul în care parolele sunt gestionate în aplicația dvs., nu modificați acest comportament.
„
Utilizare standard
Când doriți să înregistrați un nou cont de utilizator, vizualizarea pentru a face acest lucru va arăta probabil cam așa cum urmează în views.py :
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import UserCreationForm def signup(request): if request.user.is_authenticated: return redirect('/') if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') password = form.cleaned_data.get('password1') user = authenticate(username=username, password=password) login(request, user) return redirect('/') else: return render(request, 'signup.html', {'form': form}) else: form = UserCreationForm() return render(request, 'signup.html', {'form': form})
Să descompunem asta:
- Dacă utilizatorul este deja conectat, îl vom redirecționa departe de pagina de înscriere.
- Dacă metoda de solicitare este POST, înseamnă că formularul pentru crearea unui utilizator a fost deja completat și este timpul să creați un utilizator.
- Mai întâi, construiți obiectul formular pe backend cu datele furnizate de utilizator.
- Dacă formularul este valid, creați utilizatorul și conectați-l, apoi trimiteți-l pe pagina principală.
- În caz contrar, aruncați-le înapoi pe pagina de creare a utilizatorilor cu informații despre datele care nu erau valide (de exemplu, au solicitat un nume de utilizator deja folosit).
- În caz contrar, utilizatorul accesează pagina pentru prima dată și ar trebui să primească formularul de creare a unui cont nou.
Acum examinăm conectarea la cont:
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import AuthenticationForm def signin(request): if request.user.is_authenticated: return render(request, 'homepage.html') if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('/') else: form = AuthenticationForm(request.POST) return render(request, 'signin.html', {'form': form}) else: form = AuthenticationForm() return render(request, 'signin.html', {'form': form})
O altă defecțiune:
- Dacă utilizatorul este deja conectat, îl vom redirecționa departe de pagina de conectare.
- Dacă metoda de solicitare este POST, înseamnă că formularul de conectare a fost completat și este timpul să autentificați utilizatorul la un cont.
- Mai întâi, autentificați utilizatorul cu datele furnizate de utilizator
- Dacă numele de utilizator și parola corespund unui cont, conectați utilizatorul
- În caz contrar, aduceți-i înapoi la pagina de conectare cu informațiile din formular precompletate
- În caz contrar, utilizatorul accesează pagina pentru prima dată și ar trebui să primească formularul de autentificare.
În cele din urmă, utilizatorii dvs. ar putea dori în cele din urmă să se deconecteze. Codul de bază pentru această solicitare este simplu:
from django.shortcuts import render, redirect from django.contrib.auth import logout def signout(request): logout(request) return redirect('/')
Odată ce utilizatorul a fost conectat la contul său și până când se deconectează de pe acel dispozitiv, are o „sesiune”. În acest timp, solicitările ulterioare din browserul lor vor putea accesa paginile destinate exclusiv contului. Un utilizator poate avea mai multe sesiuni active în același timp. În mod implicit, sesiunile nu expiră.
În timp ce un utilizator are o sesiune activă pe dispozitivul său, se va înregistra ca True
pentru verificarea request.user.is_authenticated
. O altă modalitate de a restricționa paginile numai la utilizatorii conectați este decoratorul @login_required
de deasupra unei funcții. Există mai multe alte modalități de a realiza același lucru, detaliate aici.
Dacă acest nivel de configurare este mai mult decât doriți să efectuați, există o abordare și mai ieșită din cutie a gestionării utilizatorilor. Aceste vizualizări de autentificare stoc oferă rute, vizualizări și formulare standard pentru gestionarea utilizatorilor și pot fi modificate prin alocarea lor la adrese URL personalizate, transmiterea de șabloane personalizate sau chiar subclasificarea vizualizărilor pentru mai mult control.
Extinderea modelului utilizatorului
În general, trebuie să extindeți modelul de utilizator pentru a oferi controale de acces mai precise sau pentru a stoca mai multe date despre utilizator pentru fiecare cont. Vom explora mai jos câteva cazuri comune.
Eliminarea câmpurilor din modelul utilizatorului
Spre deosebire de antetul acestei secțiuni, nu recomand să faceți modificări direct modelului utilizatorului sau schemei bazei de date asociate! Modelul de utilizator generic este stabilit implicit în baza de date în timpul configurării unui nou proiect Django. Este atât de mult legat de modelul de utilizator implicit, încât schimbarea acestuia ar putea avea efecte neașteptate în aplicația dvs. (mai ales dacă utilizați biblioteci terțe), prin urmare, adăugarea sau eliminarea câmpurilor nu este recomandată și nu este ușoară de cadru.
În mod implicit, singurele două câmpuri care sunt necesare pentru un utilizator sunt numele de utilizator și parola. Dacă nu doriți să utilizați niciunul dintre celelalte câmpuri, pur și simplu ignorați existența acestora, deoarece un utilizator poate fi creat fără nume, prenume sau adresă de e-mail. Există o colecție de câmpuri implicite, cum ar fi last_login și date_joined, care pot fi, de asemenea, ignorate dacă nu le doriți. Dacă ați avea o constrângere tehnică reală care necesită eliminarea câmpurilor opționale din modelul utilizatorului, ați ști deja despre aceasta și nu ați avea nevoie de acest articol.
Un motiv comun pentru care ați putea dori să renunțați la un câmp în modelul de utilizator este să renunțați la numele de utilizator în favoarea e-mailului ca identificator unic. În acest caz, atunci când creați utilizatorul din datele formularului sau autentificați o solicitare, introduceți pur și simplu adresa de e-mail ca nume de utilizator, pe lângă utilizarea acesteia în câmpul de e-mail. Câmpul nume de utilizator va aplica în continuare restricția de unicitate atunci când numele de utilizator sunt formatate ca adrese de e-mail. Șirurile sunt șiruri, vor fi tratate la fel.
Este atât de mult legat de modelul de utilizator implicit, încât schimbarea acestuia ar putea avea efecte neașteptate în aplicația dvs., mai ales dacă utilizați biblioteci terțe.
„
Adăugarea câmpurilor cu un profil
În mod similar, dacă doriți să stocați informații suplimentare despre utilizatorii dvs., nu ar trebui să încercați să modificați modelul implicit de utilizator. Chiar și pentru un singur câmp, definiți-vă propriul obiect cu o relație unu-la-unu cu utilizatorii existenți. Acest model suplimentar este adesea numit Profile
. Să presupunem că doriți să stocați un al doilea nume și data nașterii (dob) pentru fiecare utilizator. Profile
ar fi definit după cum urmează în models.py :
from django.db import models from django.contrib.auth.models import User class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) middle_name = models.CharField(max_length=30, blank=True) dob = models.DateField(null=True, blank=True)
Control de acces personalizat
Este posibil ca aplicația dvs. să fi necesitat o distincție între diferitele tipuri de utilizatori pentru a accesa informații și funcții. Django oferă un sistem pentru crearea de control al accesului personalizat: permisiuni și grupuri.
Permisiunile sunt obiecte care determină accesul la resurse. Un utilizator poate avea una sau mai multe permisiuni. De exemplu, ar putea avea acces de citire la un tabel de produse și acces de scriere la un tabel de clienți. Implementarea exactă a permisiunii variază substanțial în funcție de aplicație, dar abordarea lui Django face intuitivă definirea permisiunilor pentru date și atribuirea acestor permisiuni utilizatorilor.
Aplicațiile pentru întreprinderi și alte organizații mari implementează adesea controlul accesului bazat pe roluri. În esență, un utilizator poate avea diverse roluri, fiecare dintre ele având anumite permisiuni. Instrumentul lui Django pentru implementarea acestui model este Grupul. Un grup poate avea orice număr de permisiuni, care pot fi fiecare atribuite oricărui număr de grupuri. Un utilizator obține apoi permisiuni nu direct, ci prin apartenența la grupuri, făcând aplicația mai ușor de administrat.
Prezentare generală: integrarea unui furnizor de plăți
Procesul precis de integrare a unui procesor de plăți variază substanțial în funcție de aplicație și furnizor. Cu toate acestea, voi acoperi procesul în termeni generali.
Unul dintre avantajele cheie ale externalizării plăților este că furnizorul este responsabil pentru stocarea și validarea datelor foarte reglementate, cum ar fi informațiile despre cardul de credit. Serviciul partajează apoi un simbol de utilizator unic cu aplicația dvs., împreună cu date despre istoricul plăților. Ca și adăugarea profilului, puteți crea un model asociat cu User
principal și puteți stoca datele în acel model. Ca și în cazul parolelor, este important să urmați integrarea dată cu furnizorul pentru a evita stocarea necorespunzătoare a informațiilor sensibile.
Prezentare generală: Conectare socială
Celălalt domeniu larg și complex pe care vreau să-l abordez pe scurt este conectarea socială. Platformele mari precum Facebook și Google, precum și site-urile mai mici precum GitHub oferă API-uri pentru utilizarea serviciilor lor pentru a autentifica utilizatorii. Similar cu un furnizor de plăți, aceasta creează o înregistrare în baza de date care leagă un cont la un cont din baza lor de date.
Este posibil să doriți să includeți autentificarea socială în site-ul dvs. pentru a facilita înscrierea utilizatorilor fără a crea un nou set de date de conectare. Dacă aplicația dvs. vizează numai clienții care folosesc deja un anumit site care oferă o opțiune de autentificare socială, vă poate ajuta să atrageți utilizatori de pe acea piață prin scăderea barierei de intrare. În plus, dacă aplicația dvs. intenționează să acceseze datele utilizatorului de la un serviciu terță parte, conectarea conturilor în timpul autentificării simplifică procesul de acordare a permisiunilor.
Cu toate acestea, există și dezavantaje în utilizarea auth. Modificările API sau întreruperile de la furnizorul terț ar putea întrerupe timpul de funcționare sau activitățile de dezvoltare ale aplicației dvs. În general, dependențele externe adaugă complexitate aplicației. În cele din urmă, merită să luați în considerare politicile de colectare și utilizare a datelor ale terților cu care vă integrați și asigurați-vă că acestea se aliniază cu așteptările dvs. și ale utilizatorilor dvs.
Dacă decideți că autentificarea socială este potrivită pentru aplicația dvs., din fericire, există o bibliotecă pentru asta. Python Social Auth pentru Django este un pachet pentru activarea capabilităților ecosistemului de autentificare socială al Python în proiectele Django.
Încheierea
Oricât de universal este contul de utilizator, utilizarea sa pe scară largă poate duce la rezolvarea inutilă a acelorași probleme. Sperăm că acest articol v-a arătat gama de funcții puternice disponibile în Django și v-a oferit o înțelegere a responsabilităților de bază ale unei aplicații atunci când creați conturi de utilizator.
Django Highlights este o serie care introduce concepte importante de dezvoltare web în Django. Fiecare articol este scris ca un ghid independent pentru o fațetă a dezvoltării Django menită să ajute dezvoltatorii și designerii front-end să ajungă la o înțelegere mai profundă a „cealaltă jumătate” a bazei de cod. Aceste articole sunt în mare parte construite pentru a vă ajuta să înțelegeți teoria și convențiile, dar conțin câteva exemple de cod, care sunt scrise în Django 3.0. Câteva concepte pe care le-am atins în acest articol, inclusiv șabloane, utilizatori admin, modele și formulare, vor fi explorate individual în detaliu în articolele viitoare din această serie.
Alte părți din serie:
- Repere Django: Șabloanele salvează linii (Partea a 2-a)
- Repere Django: modele, administrator și valorificarea bazei de date relaționale (partea 3)
- Repere Django: dispute active statice și fișiere media (partea a 4-a)