djoser ist eine Bibliothek, die die grundlegende Benutzerauthentifizierung und -registrierung im Django REST Framework unterstützt. Es kann auch für benutzerdefinierte Modelle verwendet werden und ist für eine Architektur konzipiert, die besser zur Single Page Application (SPA) passt, anstatt den Django-Code wiederzuverwenden.
Dieses Mal werde ich über die Implementierung der einfachsten Authentifizierungsfunktion von djoser schreiben. Beachten Sie, dass diese Authentifizierung aus Sicherheitsgründen nicht verwendet werden sollte und es stärkere Sicherheitseinstellungen gibt, wie z. B. die unten stehende JWT-Authentifizierung. Ich werde es als einfache Zertifizierung bis zum letzten einführen.
Der Quellcode ist hier
Alle folgenden Elemente können nach der Installation als Endpunkte verwendet werden.
/users/ /users/me/ /users/confirm/ /users/resend_activation/ /users/set_password/ /users/reset_password/ /users/reset_password_confirm/ /users/set_username/ /users/reset_username/ /users/reset_username_confirm/ /token/login/ (Token Based Authentication) /token/logout/ (Token Based Authentication) /jwt/create/ (JSON Web Token Authentication) /jwt/refresh/ (JSON Web Token Authentication) /jwt/verify/ (JSON Web Token Authentication) Getting started
Ich habe andere Artikel im Zusammenhang mit Djoser geschrieben.
Dieses Mal implementieren wir die Benutzerauthentifizierung mithilfe der JWT-Authentifizierung.
Der Ablauf bis zur Mitte entspricht der JWT-Authentifizierungszeit, und die wichtigsten Änderungen bestehen darin, models.py selbst zu schreiben und einige settings.py zu erhöhen.
$ pip install -U djoser
Da die JWT-Authentifizierung verwendet wird, muss auch simple_jwt verwendet werden.
$ pip install -U djangorestframework_simplejwt
Machen Sie zuerst ein Projekt
$ django-admin startproject djoser_customuser
Gehen Sie in das Projekt hinein
$ cd djoser_customuser
Erstellen Sie eine App.
$ django-admin startapp accounts
Als nächstes werden wir Django konfigurieren.
setings.py
from datetime import timedelta # add
.........
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # add
'djoser', # add
'accounts' # add
]
# add
SIMPLE_JWT = {
#Setzen Sie das Token auf JWT
'AUTH_HEADER_TYPES':('JWT'),
#Festlegen der Dauer des Tokens
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60)
}
# add
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
# add
AUTH_USER_MODEL = 'user.accounts'
urls.py
from django.contrib import admin
from django.urls import path,include #add
urlpatterns = [
path('admin/', admin.site.urls),
path('api/auth/',include('djoser.urls')), #add
path('api/auth/',include('djoser.urls.jwt')), #add
]
Von hier aus werde ich ein benutzerdefiniertes Benutzermodell für das Teil schreiben, das sich erheblich vom Artikel zur JWT-Zertifizierung unterscheidet. In Bezug darauf, warum wir ein benutzerdefiniertes Benutzermodell anstelle des Standardbenutzermodells verwenden, reicht das Standardbenutzermodell im Allgemeinen nicht aus, um die gewünschte Webanwendung zu erstellen, und die Entwicklung ist fortgeschritten. Da es schwierig ist, das Benutzermodell später zu ändern, ist es wünschenswert, ein benutzerdefiniertes Benutzermodell zu entwerfen, das die Anforderungen im Voraus erfüllt.
Darüber hinaus enthält Django zwei Klassen, die Klasse "AbstractUser" und die Klasse "AbstractBaseUser", die standardmäßig enthalten sind.
Da es der User-Klasse ähnlich ist, ist es einfach zu verwenden, da weniger Codierung erforderlich ist. Daher wird es häufig verwendet, wenn nur Attribute hinzugefügt werden.
Es erfordert mehr Codierung, da Sie den Benutzernamen und andere Attribute schreiben müssen, ist jedoch flexibler als AbstractUser.
Im Allgemeinen weist es die obigen Eigenschaften auf. Dieses Mal werden wir "AbstactBaseUser" verwenden.
models.py
from django.db import models
# add
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils import timezone
from django.core.mail import send_mail
from django.contrib.auth.base_user import BaseUserManager
# add
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, username, email, password, **extra_fields):
"""
Create and save a user with the given username, email, and password.
"""
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(username=username, email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', 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(username, email, password, **extra_fields)
class User(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=150, blank=True)
email = models.EmailField(_('email address'), blank=True,unique=True)
profile = models.CharField(_('profile'), max_length=255, blank=True) # add
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
EMAIL_FIELD = 'email' # fix
USERNAME_FIELD = 'email' # fix
REQUIRED_FIELDS = ['username'] # fix
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email)
def get_full_name(self):
"""
Return the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"""Return the short name for the user."""
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
Danach ist der Ablauf genau der gleiche wie beim JWT-Artikel. Es gibt jedoch einen Unterschied, zunächst in models.py
models.py
EMAIL_FIELD = 'email' # fix
USERNAME_FIELD = 'email' # fix
REQUIRED_FIELDS = ['username'] # fix
Bisher war der Benutzername beim Erstellen eines Benutzers ein erforderliches Element, diesmal ist jedoch E-Mail ein erforderliches Element. Wenn Sie tatsächlich einen Webdienst verwenden, sollte E-Mail ein erforderliches Element und kein Benutzername sein. Dies sind auch die Vorteile der Verwendung von benutzerdefinierten Benutzern.
Migrieren Sie und erstellen Sie einen Superuser.
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser
Email address: [email protected]
Username: Admin
Password:***********
Starten Sie auf dem lokalen Host und geben Sie an http://localhost:8000/api/auth Zugreifen.
$ python manage.py runserver
Und http://localhost:8000/api/auth/users/ Wenn Sie zugreifen
Benutzerinformationen können nicht abgerufen werden, da sie noch nicht authentifiziert sind. Also, wie beim letzten Mal, um einen Token zu bekommen http://localhost:8000/api/auth/jwt/create/ Greifen Sie zu, geben Sie den Wert des zuvor registrierten Superusers ein und drücken Sie unten rechts auf POST.
Dann wird das folgende Token ausgegeben und das Zugriffstoken unten wird kopiert.
Lassen Sie uns die Benutzerinformationen mit dem Befehl curl abrufen.
curl -LX GET http://127.0.0.1:8000/api/auth/users/me/ -H 'Authorization: JWT xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
(Geben Sie den Token in xxxx ein.)
Dann
{"username":"Admin","id":1,"email":"[email protected]"}
Die zuvor registrierten Benutzerinformationen werden zurückgegeben.
Recommended Posts