image
8 marca 2023

logowanie kont użytkowników poprzez adres e-mail

8 marca 2023

W tradycyjnym podejściu logowanie do aplikacji internetowej odbywa się za pomocą unikalnej nazwy użytkownika i hasła. Chociaż to podejście jest powszechnie stosowane, ma pewne wady, które mogą wpłynąć na wygodę użytkowników. Na przykład, użytkownik może mieć problem z zapamiętaniem swojej nazwy użytkownika, co prowadzi do potrzeby odzyskiwania danych logowania.
 

Jednym z popularnych rozwiązań tych problemów jest zastosowanie adresu e-mail jako unikalnego identyfikatora dla logowania. Adresy e-mail są nie tylko unikalne dla każdej osoby, ale także łatwiejsze do zapamiętania. Ponadto, większość użytkowników jest już przyzwyczajona do używania adresów e-mail jako identyfikatorów w różnych usługach internetowych. Wprowadzenie logowania opartego na adresie e-mail może przyczynić się do zwiększenia wygody i satysfakcji użytkowników z korzystania z aplikacji.

 

W tym artykule przedstawimy, jak zaimplementować logowanie za pomocą adresu e-mail w aplikacji Django, korzystając z funkcji "AbstractUser" oraz funkcji widoków (function based views). Przejdziemy przez proces tworzenia modelu użytkownika, formularzy, widoków, a także szablonów HTML z wykorzystaniem Bootstrap.

 

 

Tworzenie modelu użytkownika z AbstractUser

 

Aby zaimplementować logowanie za pomocą adresu e-mail, musimy najpierw utworzyć niestandardowy model użytkownika, który będzie rozszerzać wbudowany model AbstractUser. AbstractUser zawiera wszystkie podstawowe pola i metody niezbędne do zarządzania kontami użytkowników. Będziemy modyfikować ten model, aby używać adresu e-mail jako głównego identyfikatora.

 

Oto jak zbudować niestandardowy model użytkownika:

# accounts/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(unique=True, blank=False, error_messages={'unique': "A user with that email already exists!"})

    account_type = models.CharField(choices=ACCOUNT_TYPE,  max_length=10)
    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        return self.email

 

W powyższym kodzie:

 

1. Importujemy AbstractUser z django.contrib.auth.models oraz models z django.db.

 

2. Tworzymy nową klasę CustomUser, która dziedziczy po AbstractUser.

 

3. Nadpisujemy pole email w klasie CustomUser, dodając atrybut unique=True. Oznacza to, że każdy adres e-mail musi być unikalny dla każdego użytkownika.

 

4. Ustawiamy USERNAME_FIELD na 'email', co oznacza, że adres e-mail będzie używany jako identyfikator podczas logowania.

 

5. Nadpisujemy metodę '__str__', aby zwracała adres e-mail użytkownika

 

Teraz musimy zaktualizować ustawienia aplikacji, aby używać naszego niestandardowego modelu użytkownika:

# settings.py

AUTH_USER_MODEL = 'accounts.CustomUser'

 

W powyższym kodzie zastępujemy 'accounts' nazwą aplikacji, w której znajduje się model CustomUser. AUTH_USER_MODEL informuje Django, że chcemy korzystać z naszego niestandardowego modelu użytkownika zamiast domyślnego.

 

Do poprawnego działania modelu CustomUser niezbędny bedzie CustomUserManager, który został już uwzględniony przy modelu użytkownika. Oto kod odpowiedzialny za tą funkcjonalność: 

# accounts/managers.py

from django.contrib.auth.base_user import BaseUserManager

class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """
    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self.create_user(email, password, **extra_fields)
    

 

Tworzenie formularzy dla rejestracji i logowania

 

Następnie musimy utworzyć formularze, które pozwolą użytkownikom rejestrować się i logować się za pomocą swojego adresu e-mail. W tym celu utworzymy dwa formularze: UserRegisterForm i EmailLoginForm. Tworzymy nowy plik o nazwie forms.py w folderze naszej aplikacji i dodajemy następujący kod:

# accounts/forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import get_user_model

User = get_user_model()

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

class EmailLoginForm(AuthenticationForm):
    username = None
    email = forms.EmailField()
    
    class Meta:
        model = User
        fields = ['email', 'password']

 

W powyższym kodzie:

 

1. Importujemy forms z django, UserCreationForm i AuthenticationForm z django.contrib.auth.forms oraz get_user_model z django.contrib.auth.

 

2. Pobieramy niestandardowy model użytkownika za pomocą funkcji get_user_model i przypisujemy go do zmiennej User.

 

3. Tworzymy klasę UserRegisterForm, która dziedziczy po UserCreationForm. Dodajemy pole email jako wymagane pole do formularza.

 

4. W klasie Meta formularza UserRegisterForm ustawiamy model na nasz niestandardowy model użytkownika oraz definiujemy listę pól, które mają być uwzględnione w formularzu.

 

5. Tworzymy klasę EmailLoginForm, która dziedziczy po AuthenticationForm. Ustawiamy username na None, ponieważ będziemy używać adresu e-mail zamiast nazwy użytkownika. Dodajemy pole email jako wymagane pole do formularza.

 

6. W klasie Metaformularza EmailLoginForm ustawiamy model na nasz niestandardowy model użytkownika oraz definiujemy listę pól, które mają być uwzględnione w formularzu.

 

7. Teraz mamy gotowe formularze, które pozwolą użytkownikom rejestrować się i logować się za pomocą swojego adresu e-mail.

 

 

Implementacja widoków (views) dla rejestracji i logowania

 

Teraz, gdy mamy gotowe formularze, możemy utworzyć widoki, które obsługują proces rejestracji i logowania. W tym celu dodajemy następujący kod do pliku views.py w folderze naszej aplikacji:

# accounts/views.py

from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from .forms import UserRegisterForm, EmailLoginForm

def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            user = form.save()
            messages.success(request, 'Konto zostało utworzone! Możesz się teraz zalogować.')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'register.html', {'form': form})

def user_login(request):
    if request.method == 'POST':
        form = EmailLoginForm(request, request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            password = form.cleaned_data.get('password')
            user = authenticate(request, email=email, password=password)
            if user is not None:
                login(request, user)
                return redirect('home')
    else:
        form = EmailLoginForm(request)
    return render(request, 'login.html', {'form': form})

def home(request):
    return render(request, 'home.html')

 

W powyższym kodzie:

 

1.Importujemy funkcje render, redirect z modułu django.shortcuts, funkcje login i authenticate z django.contrib.auth, formularze UserRegisterForm i EmailLoginForm z pliku forms.py

 

2. Tworzymy funkcję widoku register, która obsługuje żądania POST i GET. Jeśli żądanie jest POST, tworzymy instancję formularza UserRegisterForm z danymi przesłanymi przez użytkownika. Jeśli formularz jest prawidłowy, zapisujemy nowego użytkownika i wyświetlamy wiadomość o powodzeniu, a następnie przekierowujemy użytkownika do strony logowania. Jeśli żądanie jest GET, wyświetlamy pusty formularz rejestracji.

 

3. Tworzymy funkcję widoku user_login, która obsługuje żądania POST i GET. Jeśli żądanie jest POST, tworzymy instancję formularza EmailLoginForm z danymi przesłanymi przez użytkownika. Jeśli formularz jest prawidłowy, próbujemy uwierzytelnić użytkownika za pomocą funkcji authenticate i przekazujemy adres e-mail oraz hasło. Jeśli uwierzytelnienie się powiedzie, logujemy użytkownika, wyświetlamy powitalną wiadomość i przekierowujemy go na stronę główną. Jeśli żądanie jest GET, wyświetlamy pusty formularz logowania.

4. Tworzymy funkcję widoku home do której przekierowani zostaną użytkownicy po poprawnym zalogowaniu się do aplikacji. W realnym rozwiązaniu można ją zdecydowanie bardziej rozbudować, jednak w tym przykładzie posłuży ona jedynie do potwierdzenia czy logowanie odbyło się pomyślnie.

 

Mając gotowe widoki, możemy przejść do tworzenia szablonów HTML.

 

 

Tworzenie szablonów HTML z wykorzystaniem Bootstrap

 

W tym podpunkcie zajmiemy się tworzeniem szablonów HTML dla naszych widoków rejestracji i logowania, używając Bootstrap, aby szybko i łatwo stworzyć atrakcyjne i responsywne formularze. Najpierw utworzymy katalog templates w folderze naszej aplikacji, a następnie w nim dwa pliki: register.html i login.html.

 

Zacznijmy od szablonu register.html:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rejestracja</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h2>Registration</h2>
        <form method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="btn btn-primary">register</button>
        </form>
    </div>
</body>
</html>

 

W powyższym szablonie:

 

1.Ładujemy tag static na początku pliku, aby móc korzystać ze statycznych plików (nie jest to jednak używane w tym konkretnym szablonie).

 

2. Dodajemy podstawową strukturę HTML5 z meta tagami, tagiem tytułu i linkiem do arkusza stylów Bootstrap.

 

3. Tworzymy kontener, w którym umieszczamy formularz rejestracji. Formularz korzysta z metody POST, a tag csrf_token zapewnia zabezpieczenie przed atakami CSRF.

 

4. Wyświetlamy formularz za pomocą {{ form.as_p }}, co wygeneruje formularz z polami zawartymi wewnątrz tagów <p>.

 

5. Dodajemy przycisk "Zarejestruj się" z klasą Bootstrap "btn btn-primary".

 

Teraz przejdźmy do szablonu login.html:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Log in</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h2>Log in</h2>
        <form method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="btn btn-primary">Log in</button>
        </form>
    </div>
</body>
</html>

 

Szablon login.html jest bardzo podobny do register.html. Różnice to zmiana tytułu na "Logowanie" oraz przycisku na "Zaloguj się".

 

Na końcu szablon home.html, po udanym zalogowaniu użytkownicy zostaną do niego przekierowani.

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rejestracja</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h1>Successful login!</h1>
        <h2>you are now logged in based on your email address</h2>
    </div>
</body>
</html>

 

 

Mając gotowe szablony, możemy teraz dodać odpowiednie adresy URL, aby zintegrować nasze widoki z resztą aplikacji. W tym celu edytujemy plik urls.py w folderze naszej aplikacji, dodając następujące ścieżki:

from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.register, name='register'),
    path('login/', views.user_login, name='login'),
    path('home/', views.home, name='home'),
]

 

W powyższym kodzie:

 

1. Importujemy path z modułu django.urls oraz views z naszej aplikacji.

 

2. Dodajemy ścieżki dla widoków registeruser_login oraz home, przypisując im odpowiednie nazwy.

 

W ten sposób zintegrowaliśmy nasze widoki rejestracji i logowania z aplikacją Django. Teraz użytkownicy mogą rejestrować się i logować się za pomocą swojego adresu e-mail.

 

 

Przykład rejestracji i logowania użytkownika

 

W tej części posta pokażemy, jak wygląda proces rejestracji i logowania użytkownika w naszej aplikacji Django. Przypomnijmy, że zaimplementowaliśmy funkcje rejestracji i logowania, które używają adresu e-mail zamiast nazwy użytkownika.

 

Aby przetestować naszą implementację, wykonaj poniższe kroki:

 

Przygotować oraz wykonać migrację bazy danych.

python manage.py makemigrations
python manage.py migrate

 

1. Uruchom serwer deweloperski Django, wpisując w konsoli:

python manage.py runserver

 

2. Otwórz przeglądarkę i przejdź do adresu URL rejestracji, na przykład: http://127.0.0.1:8000/register/. Zobaczysz formularz rejestracji, który utworzyliśmy wcześniej.

 

3. Wypełnij formularz, podając adres e-mail, hasło i powtórzone hasło. Upewnij się, że podane hasło spełnia wymagania dotyczące bezpieczeństwa, takie jak długość i unikalne znaki.

 

4. Kliknij przycisk "Zarejestruj się". Jeśli formularz został wypełniony poprawnie, zostaniesz przekierowany na stronę logowania z informacją o pomyślnym utworzeniu konta.

 

5. Przejdź do adresu URL logowania, na przykład: http://127.0.0.1:8000/login/. Zobaczysz formularz logowania, który również utworzyliśmy wcześniej.

 

6. Wprowadź adres e-mail i hasło, których użyłeś podczas rejestracji, a następnie kliknij przycisk "Zaloguj się".

 

7. Jeśli dane logowania są poprawne, zostaniesz przekierowany na stronę główną aplikacji (lub inną stronę, którą zdefiniowaliśmy po zalogowaniu).

Dyskusja

Twój komentarz

Tagi