Najważniejsze cechy Django: modele użytkownika i uwierzytelnianie (część 1)
Opublikowany: 2022-03-10Istnieją dwa rodzaje stron internetowych: statyczne i dynamiczne. Django to framework do tworzenia dynamicznych stron internetowych. Chociaż statyczna witryna internetowa to taka, która przedstawia wyłącznie informacje, nie ma interakcji (poza prostymi żądaniami stron), która jest rejestrowana na serwerze. W statycznej witrynie serwer wysyła do klienta kod HTML, CSS i JavaScript i to wszystko. Więcej możliwości wymaga dynamicznej witryny internetowej, w której serwer przechowuje informacje i reaguje na interakcję użytkownika, a nie tylko obsługujące strony. Jednym z głównych powodów tworzenia dynamicznej witryny jest uwierzytelnianie użytkowników i ograniczanie zawartości.
Pisanie, wdrażanie i administrowanie statyczną witryną internetową jest o rząd wielkości łatwiejsze, tańsze i bezpieczniejsze niż witryna dynamiczna. Dlatego powinieneś tworzyć dynamiczną stronę internetową tylko wtedy, gdy dodatkowe możliwości paradygmatu dynamicznego są niezbędne dla twojego projektu. Django upraszcza i usprawnia proces tworzenia dynamicznej witryny z wbudowanymi komponentami. Jako jeden z głównych elementów dynamicznej aplikacji internetowej, obiekt „konto użytkownika”, podobnie jak koło, kusi do ponownego wymyślenia, ale standardowy kształt jest odpowiedni dla większości zastosowań. Django zapewnia potężny, gotowy do użycia model użytkownika, a w tym artykule omówimy najlepszy sposób na zapewnienie bezpiecznych, intuicyjnych przepływów uwierzytelniania użytkowników.
Dalsze części w serii:
- Najważniejsze cechy Django: Szablonowanie zapisuje wiersze (część 2)
- Najważniejsze cechy Django: modele, administracja i wykorzystanie relacyjnej bazy danych (część 3)
- Najważniejsze cechy Django: walka o zasoby statyczne i pliki multimedialne (część 4)
Przygotowanie
Jeśli chcesz stworzyć własną aplikację Django, aby poeksperymentować z koncepcjami w tym artykule, możesz utworzyć katalog (i najlepiej środowisko wirtualne), a następnie uruchomić następujące polecenia:
pip install django django-admin startproject PROJECTNAME cd PROJECTNAME python manage.py startapp APPNAME python manage.py migrate python manage.py runserver
Jeśli szukasz przewodnika po tworzeniu swojego pierwszego projektu Django, własna strona internetowa Django jest świetnym rozwiązaniem. W tym artykule nie używamy przykładowego projektu, ale omówione koncepcje będą miały zastosowanie do prawie każdej aplikacji Django.
Standardowy model użytkownika
Zasadniczo koncepcja konta użytkownika istnieje z dwóch powodów: kontroli dostępu i spersonalizowanego stanu aplikacji. Kontrola dostępu polega na tym, że zasoby w systemie są dostępne tylko dla niektórych użytkowników. Spersonalizowany stan jest w dużym stopniu zależny od przeznaczenia aplikacji, ale może obejmować ustawienia, dane lub inne rekordy specyficzne dla indywidualnego użytkownika. Model User
akcji Django zapewnia rozsądne podejście do obu przypadków użycia.
Początkowo w aplikacji Django istnieją dwa rodzaje użytkowników: konta superużytkowników i zwykli użytkownicy. Superużytkownicy mają wszystkie atrybuty i przywileje zwykłych kont, ale mają również dostęp do panelu administracyjnego Django, potężnej aplikacji, którą szczegółowo omówimy w kolejnym artykule. Zasadniczo superużytkownicy mogą tworzyć, edytować lub usuwać dowolne dane w aplikacji, w tym konta innych użytkowników.
Zasadniczo koncepcja konta użytkownika istnieje z dwóch powodów: kontroli dostępu i spersonalizowanego stanu aplikacji.
“
Aby utworzyć superużytkownika we własnej aplikacji Django, uruchom:
python manage.py createsuperuser
Inną zaletą konta użytkownika jest przechowywanie spersonalizowanych danych w bazie danych. Domyślnie Django wymaga tylko nazwy użytkownika i hasła, ale udostępnia opcjonalne pola, w których użytkownicy mogą wpisać swoje imię, nazwisko i adres e-mail. Możesz przeczytać pełną referencję modelu na stronie Django. Omówimy rozszerzenie tego modelu poniżej.
Bezpieczeństwo i niezawodność
Django zawiera istotne oprogramowanie pośredniczące do zarządzania hasłami z modelem użytkownika. Hasła użytkowników muszą składać się z co najmniej 8 znaków, nie mogą być całkowicie cyframi, nie powinny być zbytnio dopasowane do nazwy użytkownika i nie znajdować się na liście 20 000 najpopularniejszych haseł. Formularze akcji Django potwierdzają te wymagania. Gdy hasło jest wysyłane do serwera, jest szyfrowane przed zapisaniem, domyślnie przy użyciu algorytmu PBKDF2 z hashem SHA256. Ogólnie rzecz biorąc, domyślny system haseł zapewnia solidne zabezpieczenia bez żadnego wysiłku ze strony programisty. Jeśli nie masz szczególnej wiedzy i ważnego powodu, aby zmienić sposób obsługi haseł w aplikacji, nie modyfikuj tego zachowania.
Inną wygodną funkcją wbudowaną jest wymóg, aby nazwy użytkowników były unikatowe. Jeśli się nad tym zastanowić, gdyby było dwóch użytkowników o nazwie użytkownika „djangofan1”, a serwer otrzymał żądanie logowania dla tej nazwy użytkownika, nie wiedziałby, który użytkownik próbuje uzyskać dostęp do aplikacji. Niestety dla nich drugi użytkownik, który spróbuje zarejestrować się z „djangofan1”, będzie musiał wybrać inną nazwę, być może „djangofan2”. To ograniczenie unikalności jest wymuszane na poziomie bazy danych, ale jest ponownie weryfikowane przez formularze dostarczane przez Django.
Na koniec uwaga dotycząca usuwania użytkowników. Chociaż usuwanie użytkowników jest możliwe, większość złożonych aplikacji będzie miała szereg zasobów powiązanych z każdym kontem użytkownika. Jeśli chcesz skutecznie usunąć użytkownika bez usuwania tych dołączonych obiektów, zamiast tego ustaw pole is_active
użytkownika na wartość false. Następnie te inne zasoby pozostają powiązane z kontem, a nie same usuwane, a konto użytkownika może zostać ponownie aktywowane w dowolnym momencie przez superużytkownika. Pamiętaj, że nie zwalnia to nazwy użytkownika, ale ustawienie konta jako nieaktywnego w połączeniu ze zmianą nazwy użytkownika na losową, unikalną wartość może osiągnąć ten sam efekt. Wreszcie, jeśli zasady Twojej witryny lub obowiązujące prawo lokalne wymagają, aby konta użytkowników można było w pełni usunąć, podejście is_active
nie będzie wystarczające.
Jeśli nie masz szczególnej wiedzy i ważnego powodu, aby zmienić sposób obsługi haseł w aplikacji, nie modyfikuj tego zachowania.
“
Standardowe zastosowanie
Kiedy chcesz zarejestrować nowe konto użytkownika, widok, który to zrobi, prawdopodobnie będzie wyglądał podobnie do tego w 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})
Rozłóżmy to:
- Jeśli użytkownik jest już zalogowany, przekierujemy go ze strony rejestracji.
- Jeżeli metodą żądania jest POST, oznacza to, że formularz do utworzenia użytkownika został już wypełniony i czas na utworzenie użytkownika.
- Najpierw skonstruuj obiekt formularza na zapleczu z danymi dostarczonymi przez użytkownika.
- Jeśli formularz jest poprawny, utwórz użytkownika i zaloguj się, a następnie wyślij na stronę główną.
- W przeciwnym razie zrzuć je z powrotem na stronę tworzenia użytkownika z informacjami o tym, jakie dane były nieprawidłowe (na przykład zażądali nazwy użytkownika, która jest już używana).
- W przeciwnym razie użytkownik wchodzi na stronę po raz pierwszy i powinien otrzymać formularz do utworzenia nowego konta.
Teraz sprawdzam logowanie na konto:
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})
Kolejny podział:
- Jeśli użytkownik jest już zalogowany, przekierujemy go ze strony logowania.
- Jeżeli metodą żądania jest POST, oznacza to, że formularz logowania został wypełniony i czas na uwierzytelnienie użytkownika do konta.
- Najpierw uwierzytelnij użytkownika za pomocą danych dostarczonych przez użytkownika
- Jeśli nazwa użytkownika i hasło odpowiadają kontu, zaloguj się użytkownika
- W przeciwnym razie sprowadź ich z powrotem na stronę logowania z wypełnionymi informacjami w formularzu
- W przeciwnym razie użytkownik wchodzi na stronę po raz pierwszy i powinien otrzymać formularz logowania.
Wreszcie Twoi użytkownicy mogą w końcu chcieć się wylogować. Podstawowy kod tego żądania jest prosty:
from django.shortcuts import render, redirect from django.contrib.auth import logout def signout(request): logout(request) return redirect('/')
Po zalogowaniu się użytkownika na swoje konto i dopóki nie wyloguje się na tym urządzeniu, odbywa się „sesja”. W tym czasie kolejne żądania z ich przeglądarki będą mogły uzyskiwać dostęp tylko do stron kont. Użytkownik może mieć jednocześnie aktywnych wiele sesji. Domyślnie sesje nie wygasają.
Podczas gdy użytkownik ma aktywną sesję na swoim urządzeniu, rejestruje się jako True
w celu sprawdzenia request.user.is_authenticated
. Innym sposobem ograniczenia stron tylko do zalogowanych użytkowników jest dekorator @login_required
nad funkcją. Istnieje wiele innych sposobów osiągnięcia tego samego, szczegółowo opisanych tutaj.
Jeśli ten poziom konfiguracji jest większy, niż chcesz wykonać, istnieje jeszcze bardziej nieszablonowe podejście do zarządzania użytkownikami. Te standardowe widoki uwierzytelniania zapewniają standardowe trasy, widoki i formularze do zarządzania użytkownikami i można je modyfikować, przypisując je do niestandardowych adresów URL, przekazując niestandardowe szablony, a nawet podklasując widoki w celu uzyskania większej kontroli.
Rozszerzenie modelu użytkownika
Ogólnie rzecz biorąc, należy rozszerzyć model użytkownika, aby zapewnić bardziej szczegółową kontrolę dostępu lub przechowywać więcej danych użytkownika na konto. Poniżej omówimy kilka typowych przypadków.
Usuwanie pól z modelu użytkownika
W przeciwieństwie do nagłówka tej sekcji, nie polecam wprowadzania zmian bezpośrednio w modelu użytkownika lub powiązanym schemacie bazy danych! Ogólny model użytkownika jest domyślnie tworzony w Twojej bazie danych podczas instalacji nowego projektu Django. Tak wiele jest związanych z domyślnym modelem użytkownika, że zmiana go może mieć nieoczekiwane skutki w aplikacji (zwłaszcza jeśli korzystasz z bibliotek innych firm), w związku z tym dodawanie lub usuwanie pól nie jest zalecane i nie jest łatwe dzięki frameworkowi.
Domyślnie jedyne dwa pola wymagane dla użytkownika to nazwa użytkownika i hasło. Jeśli nie chcesz używać żadnego z pozostałych pól, po prostu zignoruj ich istnienie, ponieważ użytkownik może zostać utworzony bez imienia, nazwiska lub adresu e-mail. Istnieje zbiór domyślnych pól, takich jak last_login i date_joined, które można również zignorować, jeśli ich nie chcesz. Gdybyś miał rzeczywiste ograniczenie techniczne, które wymagało usunięcia opcjonalnych pól z modelu użytkownika, już o tym wiedziałbyś i nie potrzebowałbyś tego artykułu.
Częstym powodem usunięcia pola w modelu użytkownika jest usunięcie nazwy użytkownika na rzecz adresu e-mail jako unikalnego identyfikatora. W takim przypadku, tworząc użytkownika z danych formularza lub uwierzytelniając żądanie, po prostu wpisz adres e-mail jako nazwę użytkownika oprócz jego użycia w polu e-mail. Pole nazwy użytkownika nadal będzie wymuszać ograniczenie unikalności, gdy nazwy użytkowników są sformatowane jako adresy e-mail. Ciągi są ciągami, będą traktowane tak samo.
Tak wiele jest związanych z domyślnym modelem użytkownika, że zmiana go może mieć nieoczekiwane efekty w Twojej aplikacji, zwłaszcza jeśli korzystasz z bibliotek innych firm.
“
Dodawanie pól z profilem
Podobnie, jeśli chcesz przechowywać dodatkowe informacje o swoich użytkownikach, nie powinieneś próbować modyfikować domyślnego modelu użytkownika. Nawet dla jednego pola zdefiniuj własny obiekt w relacji jeden-do-jednego z istniejącymi użytkownikami. Ten dodatkowy model jest często nazywany Profile
. Załóżmy, że chcesz zapisać drugie imię i datę urodzenia (dobę) dla każdego użytkownika. Profile
zostałby zdefiniowany w następujący sposób w 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)
Niestandardowa kontrola dostępu
Twoja aplikacja mogła wymagać rozróżnienia między różnymi typami użytkowników w celu uzyskania dostępu do informacji i funkcji. Django zapewnia system do tworzenia niestandardowej, szczegółowej kontroli dostępu: uprawnień i grup.
Uprawnienia to obiekty określające dostęp do zasobów. Użytkownik może mieć jedno lub więcej uprawnień. Na przykład mogą mieć dostęp do odczytu do tabeli produktów i do zapisu do tabeli klientów. Dokładna implementacja uprawnień różni się znacznie w zależności od aplikacji, ale podejście Django sprawia, że definiowanie uprawnień do danych i przypisywanie ich użytkownikom jest intuicyjne.
Aplikacje dla przedsiębiorstw i innych dużych organizacji często wdrażają kontrolę dostępu opartą na rolach. Zasadniczo użytkownik może mieć różne role, z których każda ma określone uprawnienia. Narzędziem Django do realizacji tego wzorca jest Grupa. Grupa może mieć dowolną liczbę uprawnień, z których każde można przypisać do dowolnej liczby grup. Użytkownik uzyskuje wtedy uprawnienia nie bezpośrednio, ale poprzez członkostwo w grupach, co ułatwia administrowanie aplikacją.
Przegląd: integracja dostawcy płatności
Dokładny proces integracji procesora płatności różni się znacznie w zależności od aplikacji i dostawcy. Jednak omówię ten proces w sposób ogólny.
Jedną z kluczowych zalet outsourcingu płatności jest to, że dostawca jest odpowiedzialny za przechowywanie i weryfikację ściśle regulowanych danych, takich jak informacje o karcie kredytowej. Usługa udostępnia następnie Twojej aplikacji unikalny token użytkownika wraz z danymi o historii jego płatności. Podobnie jak w przypadku dodawania profilu, możesz utworzyć model powiązany z głównym User
i przechowywać dane w tym modelu. Podobnie jak w przypadku haseł, ważne jest, aby przestrzegać podanej integracji z dostawcą, aby uniknąć niewłaściwego przechowywania poufnych informacji.
Przegląd: logowanie społecznościowe
Inną obszerną, złożoną dziedziną, którą chcę pokrótce poruszyć, jest logowanie w serwisach społecznościowych. Duże platformy, takie jak Facebook i Google, a także mniejsze witryny, takie jak GitHub, udostępniają interfejsy API do korzystania z ich usług w celu uwierzytelniania użytkowników. Podobnie jak w przypadku dostawcy płatności, tworzy to rekord w Twojej bazie danych łączący konto z kontem w ich bazie danych.
Możesz chcieć uwzględnić w witrynie uwierzytelnianie społecznościowe, aby ułatwić użytkownikom rejestrację bez tworzenia nowego zestawu danych logowania. Jeśli Twoja aplikacja jest skierowana wyłącznie do klientów, którzy już korzystają z określonej witryny, która udostępnia opcję uwierzytelniania społecznościowego, może to pomóc w przyciągnięciu użytkowników z tego rynku poprzez obniżenie bariery wejścia. Ponadto, jeśli Twoja aplikacja zamierza uzyskać dostęp do danych użytkownika z usługi innej firmy, powiązanie kont podczas uwierzytelniania upraszcza proces nadawania uprawnień.
Istnieją jednak wady korzystania z uwierzytelniania społecznościowego. Zmiany interfejsu API lub przerwy w dostawie przez zewnętrznego dostawcę mogą spowodować przerwanie działania aplikacji lub działań programistycznych. Ogólnie zależności zewnętrzne zwiększają złożoność aplikacji. Na koniec warto zastanowić się nad zasadami gromadzenia i wykorzystywania danych stron trzecich, z którymi się integrujesz, i upewnić się, że są one zgodne z oczekiwaniami Twoimi i Twoich użytkowników.
Jeśli zdecydujesz, że uwierzytelnianie społecznościowe jest odpowiednie dla Twojej aplikacji, na szczęście istnieje na to biblioteka. Python Social Auth for Django to pakiet umożliwiający udostępnienie możliwości ekosystemu social auth Pythona w projektach Django.
Zawijanie
Choć konto użytkownika jest uniwersalne, jego powszechne używanie może prowadzić do niepotrzebnego rozwiązywania tych samych problemów. Mamy nadzieję, że ten artykuł pokazał ci szereg potężnych funkcji dostępnych w Django i dał ci zrozumienie podstawowych obowiązków aplikacji podczas tworzenia kont użytkowników.
Django Highlights to seria wprowadzająca ważne koncepcje tworzenia stron internetowych w Django. Każdy artykuł jest napisany jako samodzielny przewodnik po aspekcie rozwoju Django, który ma pomóc programistom i projektantom front-end w osiągnięciu głębszego zrozumienia „drugiej połowy” bazy kodu. Artykuły te są w większości skonstruowane tak, aby pomóc Ci zrozumieć teorię i konwencję, ale zawierają kilka przykładów kodu, które zostały napisane w Django 3.0. Kilka koncepcji, które poruszyliśmy w tym artykule, w tym szablony, administratorzy, modele i formularze, zostanie szczegółowo omówionych w kolejnych artykułach z tej serii.
Dalsze części w serii:
- Najważniejsze cechy Django: Szablonowanie zapisuje wiersze (część 2)
- Najważniejsze cechy Django: modele, administracja i wykorzystanie relacyjnej bazy danych (część 3)
- Najważniejsze cechy Django: walka o zasoby statyczne i pliki multimedialne (część 4)