[PYTHON] Verschiedene Hinweise zum Django REST-Framework

http://www.django-rest-framework.org/

Informationen zur Authentifizierungsverarbeitung mithilfe von Token

Ich wollte ein Token ausstellen, als ich mich zum ersten Mal mit einer Benutzer-ID und einem Kennwort authentifizierte, und dieses Token dann in die Anforderung aufnehmen. Deshalb habe ich es wie folgt implementiert (verwenden Sie die Django-Benutzertabelle so wie sie ist). ..

Neuer Registrierungsprozess für Benutzerinformationen

Bei der Registrierung von Benutzerinformationen in der Benutzertabelle wird nur das Kennwort mithilfe der Django-Bibliothek gehasht und registriert. https://docs.djangoproject.com/en/1.8/_modules/django/contrib/auth/hashers/#make_password

serializers.py


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'password')
        write_only_fields = ('password')
        read_only_fields = ('id')
        
        def create(self, validated_data):
          """
Registrieren Sie sich nach dem Hashing des Passworts(Django verwenden Standardbibliothek)
          """
          password = validated_data.get('password')
          validated_data['password'] = make_password(password)
          return User.objects.create(**validated_data)
        
        # ......

Token-Generierung

Ich habe die Token-Authentifizierungsfunktion des Django REST-Frameworks so wie sie ist verwendet. http://www.django-rest-framework.org/api-guide/authentication/

settings.py


INSTALLED_APPS = (
    # .......
    'rest_framework.authtoken',
)

Fügen Sie einen Prozess zum Erstellen einer Token-Tabelle hinzu

models.py


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    """
Wenn ein neuer Benutzer erstellt wird, wird TOKEN automatisch ausgegeben.
    """
    if created:
        Token.objects.create(user=instance)

Mit den obigen Einstellungen wird, wenn ein Benutzer in der Benutzertabelle registriert ist, ein Token ausgegeben und in der Token-Tabelle gespeichert.

Ausgabe von Token

Weisen Sie einem beliebigen URI get_auth_token zu und erstellen Sie einen Endpunkt für den Client, um das Token abzurufen.

urls.py


from rest_framework.authtoken import views as auth_views
urlpatterns = patterns('',
    url(r'^api-token-auth/', auth_views.obtain_auth_token),
)

Wenn Sie die JSON-Datei mit Benutzername und Kennwort wie unten gezeigt POSTEN, wird das dem Benutzernamen entsprechende Token zurückgegeben.

$ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"username":"test","password":"111111"}' https://127.0.0.1:8000/api/api-token-auth/

Wenn Sie eine Anforderung vom Client an einen URI senden, für den ein Token erforderlich ist, ist es in Ordnung, wenn Sie das Token wie folgt in die Autorisierung des HTTP-Headers einfügen.

$ curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'

Authentifizierungsprozess mithilfe von Token

Wenn es sich um einen normalen Authentifizierungsprozess handelt und Sie settings.py die folgenden Einstellungen hinzufügen, wird der Inhalt des Tokens überprüft und der Authentifizierungsprozess ausgeführt, wenn eine Anforderung eingeht.

settings.py


REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}

Wenn Sie diese Einstellung vornehmen, wird die Tokenauthentifizierung standardmäßig für alle Anforderungen an URIs durchgeführt. Wenn Sie also die Authentifizierungsmethode für einige URIs ändern möchten, verwenden Sie Ihre eigene Authentifizierung, wie im folgenden Beispiel gezeigt. Sie können eine Klasse definieren, den Authentifizierungsprozess darin schreiben und diese Klasse in der Ansichtsklasse angeben.

Beachten Sie übrigens, dass dem auf dem Client angegebenen Feldnamen des HTTP-Headers automatisch "HTTP_" vorangestellt wird. Es sieht aus wie Djangos Spezifikationen.

authentications.py


class FooAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        #Bewerten Sie das feste Standardtoken während des POST
        if request.method == 'POST':
            default_token = request.META.get('HTTP_DEFAULT_TOKEN')
            try:
                token = System.objects.get(key='HTTP_DEFAULT_TOKEN')
            except Token.DoesNotExist:
                raise exceptions.AuthenticationFailed('error')

            if default_token != token.value:
                raise exceptions.AuthenticationFailed('error')

            return None
        #Wenn Sie etwas anderes als POST ausführen können, bewerten Sie das für jeden registrierten Wert ausgestellte Authentifizierungstoken.
        else:
            auth_token = request.META.get('HTTP_AUTHORIZATION')
            if not auth_token:
                raise exceptions.AuthenticationFailed('Authentication token is none')
            try:
                user = Token.objects.get(key=auth_token.replace('Token ', ''))
            except Token.DoesNotExist:
                raise exceptions.AuthenticationFailed('error')

            return (user.user, None)

view.py


class FooViewSet(viewsets.ModelViewSet):
    queryset = Foo.objects.none()
    serializer_class = FooSerializer
    authentication_classes = (FooAuthentication, )
    
    # .......

Wenn Sie sich dagegen nur mit einigen URIs authentifizieren möchten, sollten Sie TokenAuthentication in authentication_classes der Ansichtsklasse angeben.

Über den Testcode

Der Testcode verwendete den REST-Framework-API-Client. http://www.django-rest-framework.org/api-guide/testing/ So was.

tests.py


class UserTests(APITestCase):
    def setUp(self):
        """
        setUp for testing
        """
        User.objects.create(username='user1', password='user1')
        User.objects.create(username='user2', password='user2')
        self.user1 = User.objects.get(username='user1')
        self.user2 = User.objects.get(username='user2')

    def test_user_list_normal1(self):
        """
        user-list: normal pattern
        """
        url = reverse('user-list')
        expected_data = {
            "count": 1,
            "next": None,
            "previous": None,
            "results": [{
                "id": 1,
                "username": "user1"
            }]
        }
        token = Token.objects.get(user=self.user1).key
        #Token für Autorisierung setzen
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
        response = self.client.get(url, None, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        #Bestätigen Sie, dass json wie erwartet zurückgegeben wird
        self.assertEqual(response.data, expected_data)

Recommended Posts

Verschiedene Hinweise zum Django REST-Framework
Verschiedene Hinweise zur Bereitstellung der Django-App auf Heroku
Verstehen Sie den Komfort des Django Rest Framework
Grundlagen des Django REST-Frameworks
Tipps zum Django Rest Framework
Lassen Sie uns eine Todo-App mit dem Django REST-Framework erstellen
Lernnotizen für die Migrationsfunktion im Django-Framework (3)
[Django Rest Framework] Passen Sie die Filterfunktion mit Django-Filter an
Lernnotizen für die Migrationsfunktion im Django-Framework (1)
Django REST Framework Stolperstein
Django REST Framework mit Vue.js
Melden Sie sich mit dem Django Rest Framework an
So schreiben Sie eine benutzerdefinierte Validierung in Django REST Framework
[Django] Verwenden Sie MessagePack mit dem Django REST-Framework
Django Memo
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
Django Memo
Erstellen Sie eine RESTful-API mit dem Django Rest Framework
Logisches Löschen in Django, DRF (Django REST Framework)
Ein Verwaltungstool, das sofort mit dem REST-Framework ng-admin + Django erstellt werden kann
CRUD GET mit Nuxt & Django REST Framework ②
CRUD POST mit Nuxt & Django REST Framework
CRUD GET mit Nuxt & Django REST Framework ①
Überlegungen zum Design von Django REST Framework + Clean Architecture
CRUD PUT, DELETE mit Nuxt & Django REST Framework
Über den Test
[Django] as_view () Notizen
Anmerkungen zu mit
Lösung, wenn nicht gefunden, wird angezeigt, wenn die API von Django REST Framework von außen aufgerufen wird
Django REST Framework Ein wenig nützlich zu wissen.
Implementieren Sie die JWT-Anmeldefunktion im Django REST-Framework
Hinweise zu Pytorch
Wissensnotizen erforderlich, um das Python-Framework zu verstehen
Implementierung der Authentifizierungsfunktion in Django REST Framework mit djoser
Über die Warteschlange
Ein paar süchtig machende Informationen über Cliff, das CLI-Framework
Erstellen Sie eine Todo-App mit Django REST Framework + Angular
Weitere neue Benutzerauthentifizierungsmethoden mit Django REST Framework
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 1 ~
Erstellen Sie eine API für die Benutzerauthentifizierung mit Django REST Framework
Wenn Sie mit dem Django REST-Framework filtern möchten
Listenmethode für verschachtelte Ressourcen im Django REST-Framework
Implementieren Sie die API mit explosiver Geschwindigkeit mithilfe des Django REST Framework
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 2 ~
Persönliche Hinweise zur Integration von vscode und anaconda
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 3 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 4 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 5 ~
Implementieren Sie hierarchische URLs mit drf-verschachtelten Routern im Django REST-Framework
Django Python Web Framework
Erstellen einer API, die mit BERT im Django REST-Framework negativ-positive Inferenzergebnisse zurückgibt
Sellerie-Notizen zu Django
Informationen zur Entfaltungsfunktion
Über den Servicebefehl
Das Common Clk Framework
Erstes Python-Memo
[Django] Benennen Sie das Projekt um
Über die Verwirrungsmatrix