[PYTHON] Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 5] ~ Benutzerauthentifizierung ~ eine nervenschwächende Anwendung erstellen

<< Teil 4 | Teil 6 >>

Benutzerdefinierte Benutzererstellung

Beim Starten eines neuen Projekts wird dringend empfohlen, ein benutzerdefiniertes Benutzermodell zu erstellen, auch wenn der Standardbenutzer ausreicht.

Dies ist offiziell der Fall. Erstellen Sie daher einen benutzerdefinierten Benutzer.

Benutzeranwendung erstellen

$ django-admin startapp users

Fügen Sie die erstellte Anwendung zu settings.py hinzu

settings.py


.
..
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'users', #Nachtrag
]
...
..
.

Benutzermodellerstellung

users/models.py


from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager
from django.utils import timezone

# Create your models here.
class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField('username', max_length=150, unique=True)
    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)
    is_staff = models.BooleanField('is_staff', default=False)
    is_active = models.BooleanField('is_active', default=True)
    date_joined = models.DateTimeField('date joined', default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    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)

Erstellung der UserManager-Klasse

users/user_manager.py



from django.contrib.auth.base_user import BaseUserManager

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)

Bearbeiten Sie das erstellte Benutzermodell

users/models.py


.
..
...
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin #UserManager löschen
from users.user_manager import UserManager #Importieren Sie Ihre eigene UserManager-Klasse
...
..
.

Zu settings.py hinzugefügt, damit das benutzerdefinierte Benutzermodell als Authentifizierungsmodell verwendet wird

settings.py


.
..
...
AUTH_USER_MODEL = 'users.User'
...
..
.

DB-Migration

$ python3 manage.py makemigrations
Migrations for 'users':
  users/migrations/0001_initial.py
    - Create model User

Beim Migrieren ist ein Fehler aufgetreten ... Es ist eine Geschichte, in der von Anfang an ein benutzerdefinierter Benutzer erstellt und die Datenbank migriert wird

$ python3 manage.py migrate
$ python3 manage.py migrate
Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
...
..
.
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'.

Bearbeiten Sie settings.py und urls.py

settings.py


.
..
...
INSTALLED_APPS = [
    # 'django.contrib.admin',Auskommentieren
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'users',
]
...
..
.

config/urls.py


.
..
...
urlpatterns = [
    # path('admin/', admin.site.urls), #Auskommentieren
    url('api/', include(ROUTER.urls)),
]

Wieder mein Großer

$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: auth, contenttypes, sessions, users
Running migrations:
  Applying users.0001_initial... OK

Kommentieren Sie settings.py und urls.py aus und stellen Sie sicher, dass die DB-Migration nicht zu einem Fehler führt.

$ python3 manage.py makemigrations
No changes detected

$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, users
Running migrations:
  No migrations to apply.

gelöst. (Bitte erstellen Sie einen Superuser.)

Lassen Sie uns eine API mit User erstellen.

Erstellen Sie serializers.py direkt unter dem Benutzerverzeichnis

users/serializers.py


from rest_framework.serializers import ModelSerializer
from users.models import User

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

Ansicht erstellen

users/views.py


from rest_framework.viewsets import ModelViewSet
from users.models import User
from users.serializers import UserSerializer

# Create your views here.
class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

Bearbeiten Sie urls.py

config/urls.py


"""config URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from rest_framework import routers
from users.views import UserViewSet #hinzufügen

ROUTER = routers.DefaultRouter()
ROUTER.register('users', UserViewSet) #hinzufügen


urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/', include(ROUTER.urls)),
]

Greifen Sie auf http://127.0.0.1:8000/api/users/ zu.

image.png

Wenn Sie von hier aus einen Benutzer per POST erstellen, wird das Kennwort im Klartext erstellt. Dies ist eine schreckliche Situation.

Bearbeiten Sie serializers.py so, dass das Passwort gehasht wird.

users/serializers.py


from rest_framework.serializers import ModelSerializer
from users.models import User
from django.contrib.auth.hashers import make_password #hinzufügen

class UserSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

    #Überschreiben Sie die Erstellungsmethode
    def create(self, validated_data):
        password = validated_data.get('password', None)
        if password is not None:
            validated_data['password'] = make_password(password)
        return super().create(validated_data);

Installation und Konfiguration der Authentifizierungsbibliothek (JWT)

Dieses Mal werden wir die JWT-Methode verwenden. Als offiziell festlegen.

pip3 install djangorestframework-jwt

settings.py


.
..
...
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

config/urls.py


"""config URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from rest_framework import routers
from users.views import UserViewSet
from rest_framework_jwt.views import obtain_jwt_token #hinzufügen

ROUTER = routers.DefaultRouter()
ROUTER.register('users', UserViewSet)


urlpatterns = [
    path('admin/', admin.site.urls),
    url('api/', include(ROUTER.urls)),
    url('api-token-auth/', obtain_jwt_token), #hinzufügen
]

Wenn ich auf http://127.0.0.1:8000/api/users/ zugreife, wird das Ergebnis nicht mehr angezeigt. image.png

Holen Sie sich Token mit Locken

curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"admin"}' http://127.0.0.1:8000/api-token-auth/

Akquisitionsergebnis

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTgwOTIwNDcwLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvLmpwIn0.O8h4Js07Nr3aILHZyoAYlPklSGX-TJZs6k6tpB4xd0Y"}(concentration) tabatadikinoMBP:concentratio tabatadaiki$ curl -X "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTgwOTIwMzA5LCJlbWFpbCI6ImFkbWluQGFkbWluLmNvLmpwIn0.vvKtzWk6d0qhDpwy3PgyiZ6ovkw-2JHJyn7mf25XrsU"

Holen Sie sich Benutzer, indem Sie das erhaltene Token angeben

curl -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTgwOTIwMzA5LCJlbWFpbCI6ImFkbWluQGFkbWluLmNvLmpwIn0.vvKtzWk6d0qhDpwy3PgyiZ6ovkw-2JHJyn7mf25XrsU" http://127.0.0.1:8000/api/users/

Akquisitionsergebnis

[{"id":1,"password":"pbkdf2_sha256$150000$lLUvsL7bxcSs$/PhUu6BtJVaQtuhfkI6rj7frwvLHbpVFjFoCY7S8+0w=","last_login":null,"is_superuser":true,"username":"admin","first_name":"","last_name":"","email":"[email protected]","is_staff":true,"is_active":true,"date_joined":"2020-02-04T15:23:57.201798Z","groups":[],"user_permissions":[]},{"id":2,"password":"yktgy780","last_login":null,"is_superuser":true,"username":"tabatadaiki","first_name":"tabata","last_name":"daiki","email":"[email protected]","is_staff":true,"is_active":true,"date_joined":"2020-02-05T15:21:26.470920Z","groups":[],"user_permissions":[]},{"id":3,"password":"akasatana","last_login":null,"is_superuser":true,"username":"a","first_name":"a","last_name":"a","email":"","is_staff":true,"is_active":true,"date_joined":"2020-02-05T15:27:12.682966Z","groups":[],"user_permissions":[]},{"id":5,"password":"pbkdf2_sha256$150000$v9YkaBjzyGXP$VyQEp/yk6gWf8FEvI7C9TxCBANgXi9JxivQ/wjkjjpg=","last_login":null,"is_superuser":true,"username":"tabata","first_name":"tabata","last_name":"tabata","email":"","is_staff":true,"is_active":true,"date_joined":"2020-02-05T15:41:50.518882Z","groups":[],"user_permissions":[]}]

Es sieht so aus, als könnte ich mich authentifizieren.

Recommended Posts

Machen wir eine nervenschwächende Anwendung mit Vue.js und Django-Rest-Framework [Teil 6] ~ Benutzerauthentifizierung 2 ~
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 5] ~ Benutzerauthentifizierung ~ eine nervenschwächende Anwendung erstellen
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 2] ~ Vue setup ~ eine nervenschwächende App erstellen
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 1] ~ Django-Setup ~ eine nervenschwächende App erstellen
Lassen Sie uns mit Vue.js und Django-Rest-Framework [Teil 4] eine nervenschwächende Anwendung machen ~ MySQL-Konstruktion und DB-Migration mit Docker ~
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 2 erstellen
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 3 erstellen
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 4 erstellen
Versuchen Sie, ein einfaches Spiel mit Python 3 und iPhone zu erstellen
Lassen Sie uns eine Mac-App mit Tkinter und py2app erstellen
Lassen Sie uns mit Python einen Web-Socket-Client erstellen. (Zugriffstoken-Authentifizierung)
Lassen Sie uns eine GUI mit Python erstellen.
Machen wir einen Blockbruch mit wxPython
Lassen Sie uns ein Diagramm mit Python erstellen! !!
Machen wir mit xCAT einen Spacon
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 4 sichtbar
Lassen Sie uns mit Python ein Shiritori-Spiel machen
Lassen Sie uns mit Python langsam sprechen
Lassen Sie uns mit PLY 1 eine einfache Sprache erstellen
Erstellen Sie ein Webframework mit Python! (1)
Machen wir mit Pylearn 2 eine dreiäugige KI
Machen wir einen Twitter-Bot mit Python!
Erstellen Sie ein Webframework mit Python! (2)
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 3 sichtbar
Lassen Sie uns mit Flask eine Webanwendung zur Konvertierung von A nach B erstellen! Von Grund auf neu ...
Versuchen Sie, eine Webanwendung mit Vue.js und Django (Mac Edition) zu erstellen - (1) Umgebungskonstruktion, Anwendungserstellung
Ersetzen wir UWSC durch Python (5) Machen wir einen Roboter
Lassen Sie uns eine App erstellen, die ähnliche Bilder mit Python und Flask Part1 durchsuchen kann
Lassen Sie uns eine App erstellen, die ähnliche Bilder mit Python und Flask Part2 durchsuchen kann
Lass uns ein Makefile machen und es bauen (super Anfänger)
[Lass uns mit Python spielen] Ein Haushaltsbuch erstellen
Lassen Sie uns das Abhängigkeitsmanagement mit pip etwas einfacher machen
[Super einfach] Machen wir einen LINE BOT mit Python.
Erstellen Sie mit Flask-AppBuilder ganz einfach Authentifizierung, Benutzerverwaltung und mehrsprachige Systeme
Erstellen Sie mit QGIS Part 2 ein tky2jgd-Plug-In ohne praktische Anwendbarkeit
Verknüpfen Sie Python Enum mit einer Funktion, um es aufrufbar zu machen
Erstellen eines tky2jgd-Plug-Ins ohne praktische Anwendbarkeit mit QGIS Teil 1
Erstelle ein 2D-Rollenspiel mit Ren'Py (3) -Items and Tool Shop
Lassen Sie uns ein Diagramm erstellen, auf das mit IPython geklickt werden kann
Machen Sie ein BLE-Thermometer und ermitteln Sie die Temperatur mit Pythonista3