.. _jwt_token_authentication: .. index:: single: JWT JWT Token Authentifizierung ********************************* Um JWT Token zu nutzen installieren wir zuerst das Paket ``Simple JWT``. SIMPLE JWT installieren ====================== Wir legen in der ``requirements.in`` fest: .. code-block:: bash # andere Apps djangorestframework-simplejwt und installieren sie: .. code-block:: bash (eventenv) pip-compile requirements.in (eventenv) pip-sync requirements.txt requirements-dev.txt Mehr zu Simple JWT in der Doku: ``_ Settings ---------- in den Settings müssen wir die Authentication-Classes angeben: .. code-block:: python REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], } Urls --------- In den Projekt-URLs unter ``event_manager/event_manager/urls.py`` legen wir die URls fest .. code-block:: python from django.urls import path from rest_framework_simplejwt import views as jwt_views urlpatterns = [ # andere URLs path('api/jwt/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/jwt/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'), ] Pages App ----------- in der Pages App legen wir ein neues Verzeichnis unter ``event_manager/pages/api`` an und tragen in die Datei ``views.py`` folgende Beispiel-View .. code-block:: python from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated class PagesView(APIView): permission_classes = (IsAuthenticated,) def get(self, request): content = {"message": "Hello, World!"} return Response(content) Unter ``event_manager/pages/api/urls.py`` tragen wir die entsprechenden Urls ein: .. code-block:: python from django.urls import path from . import views urlpatterns = [ path('hello/', views.PagesView.as_view(), name='hello'), ] Obtain Token ============ Um den Token zu erhalten, müssen wir den Endpunkt für obtain_token aufrufen: .. code-block:: bash curl -X POST -d "username=admin&password=GEHEIM" 127.0.0.1:8000/api/jwt/token/ Der Rückgabwert besteht aus einem ``access`` und einem ``refresh`` - Token. gekürzte Ausgabe: .. code-block:: bash {"refresh":"8BXUOongUbaAnnDFESMEMsw", "access":"ji9y0MXiu1MfoqMv7ZeBTkrXUAxWiHBouKmFYoh97E"} Danach werden sowohl der access-Token als auch das refresh-Token auf der Client-Seite gespeichert, normalerweise im localStorage des Browsers. Der access-token ist fünf Minuten gültig, danach muss er erneuert werden. Um die Resource jetzt aufzufen muss der acces-token mitgesendet werden: .. code-block:: bash curl -X GET -H "Authorization: Bearer " http://127.0.0.1:8000/pages/api/hello/ {"message":"Hello, World!"} REFRESH TOKEN ----------------- Um einen neuen Token zu erhalten, kann man den Refresh URL nutzen. Als Ergebnis erhält man einen neuen Access Token: .. code-block:: bash curl -X POST -d "" 127.0.0.1:8000/api/jwt/token/refresh/ {"access":} Das Refresh-Token ist für die nächsten 24 Stunden gültig. Wenn es schließlich auch abläuft, muss der Benutzer eine vollständige Authentifizierung mit seinem Benutzernamen und Passwort durchführen, um einen neuen Satz von Zugangstoken und Refresh-Token zu erhalten. Auf den ersten Blick mag das Aktualisierungs-Token sinnlos erscheinen, tatsächlich ist es aber notwendig, um sicherzustellen, dass der Benutzer noch über die richtigen Berechtigungen verfügt. Wenn Ihr Zugangstoken eine lange Ablaufzeit hat, kann es länger dauern, die mit dem Token verbundenen Informationen zu aktualisieren. Das liegt daran, dass die Authentifizierungsprüfung mit kryptografischen Mitteln erfolgt, anstatt die Datenbank abzufragen und die Daten zu verifizieren. Einige Informationen werden also gewissermaßen zwischengespeichert. Es gibt auch einen Sicherheitsaspekt in dem Sinne, dass das Refresh-Token nur in den POST-Daten unterwegs ist. Und das Zugriffstoken wird über einen HTTP-Header gesendet, der auf dem Weg protokolliert werden kann. Dies bietet also auch ein kurzes Zeitfenster, falls Ihr Zugriffstoken kompromittiert werden sollte. Ein Refresh-Token erhält ein Zugriffstoken, ohne dass der Benutzer seine Anmeldedaten eingeben muss, um die Sitzung des Benutzers zu verlängern. Dies bietet eine nahtlose Benutzererfahrung und verbessert die Sicherheit, da der Benutzer seine Anmeldeinformationen weniger oft eingeben muss. Swagger UI =========== Die API - Endpunkte wurden alle ebenfalls in der SWAGGER Ui gesammelt und können ausprobiert werden. in das Feld "Authenticate" muss der access-Token kopiert werden: API Endpunkte für User Authentication ======================================= Die Endpunkte, die Django per Default für Login, Registierung und so weiter anbietet, eignen sich nicht für das Django Rest Framework. Hier bietet sich die App "Djoser" an: ``_ REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such as registration, login, logout, password reset and account activation. It works with custom user model. Instead of reusing Django code (e.g. PasswordResetForm), we reimplemented few things to fit better into Single Page App architecture. gutes Tutorial: https://fathinah.medium.com/calling-rest-api-with-jwt-authentication-in-django-b1c48b8018ed React Anwendung mit Djoser ============================== https://www.section.io/engineering-education/social-authentication-with-djoser-in-react-applications/