Im Moment arbeite ich aktiv an einer Anwendung, die mit der REST-API einer Django-Site funktioniert. Und einer der ersten Schritte bestand darin, die Benutzerauthentifizierung per Token einzurichten, aber damit dies funktioniert, müssen Sie zuerst ein Autorisierungstoken erhalten.
Schauen wir uns an, wie dies geschehen kann.
Django Rest Framework installieren
Da dies der allererste Artikel zur Verwendung von DRF ist, werde ich den Prozess der Installation und Konfiguration von DRF ausführlicher beschreiben. Im Folgenden werde ich diese Anweisungen nicht mehr geben.
Installieren Sie DRF und andere erforderliche Pakete
pip install djangorestframework pip install markdown # Markdown support for the browsable API. pip install django-filter
Fügen Sie als Nächstes die Anwendung „rest_frameword“ zu INSTALLED_APPS in der Site-Konfigurationsdatei settings.py hinzu
INSTALLED_APPS = [ ... 'rest_framework', ]
Darüber hinaus schlägt die offizielle Dokumentation vor, die Login- und Logout-Ansicht von rest_framework in die Datei urls.py aufzunehmen, damit Sie die API bequem im Browser verwenden können.
Um ehrlich zu sein, verwende ich diese API nicht, weil es für mich bequemer ist, die durch Swagger generierte Dokumentation zu verwenden, auf die ich später noch zu sprechen komme, aber ich verbinde trotzdem die View-Daten, damit ich keine zufälligen Probleme löse später.
urlpatterns = [ ... path('api-auth/', include('rest_framework.urls')), ]
Konfigurieren Sie als Nächstes die Standardauthentifizierung und die Berechtigungsklassen (auch in settingsp.py).
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], }
Jetzt ist alles bereit, um einen Zugangspunkt zu schreiben, um einen Token zu erhalten. Aber zuerst möchte ich die Generierung der Swagger-Dokumentation anschließen. Es ist einfach bequemer so zu arbeiten, mir gefällt zum Beispiel die redoc-Dokumentation sehr gut, in der alles recht schön und übersichtlich dargestellt wird.
Swagger installieren
Und jetzt werden wir Swagger sofort auf der Website verbinden. Ich verstehe, dass dies nicht mit dem Thema des Artikels zusammenhängt, aber im Code mache ich spezielle Manipulationen, um eine spezielle Dokumentationsanzeige zu ermöglichen, und ich denke, dass dies in Zukunft für Sie nützlich sein kann, weil:
- Sie werden in Zukunft Swagger verwenden
- Manchmal müssen Sie die Ausgabe von Informationen in der API-Beschreibung anpassen, nämlich für das Token hatte ich die spezifischste Änderung für Swagger.
Установим drf-yasg
Führen Sie dazu gemäß der Dokumentation den folgenden Befehl aus
pip install -U drf-yasg
Dann ändern wir die Datei settings.py
INSTALLED_APPS = [ ... 'django.contrib.staticfiles', # required for serving swagger ui's css/js files 'drf_yasg', ... ]
Und jetzt registrieren wir Swagger in den Site-URLs
from django.urls import re_path from drf_yasg import openapi from drf_yasg.views import get_schema_view from rest_framework import permissions schema_view = get_schema_view( openapi.Info( title="EXAMPLE API", default_version='v1', description="REST API Documentation", contact=openapi.Contact(email="example@example.com"), ), public=True, permission_classes=(permissions.IsAdminUser,), ) urlpatterns = [ ... re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), ]
Wenn Sie sich den Code genau ansehen, werden Sie feststellen, dass ich den Swagger nur für die Verwaltung der Website registriert habe. Wenn Sie möchten, dass die Dokumentation geöffnet ist, entfernen Sie diese Zeile
permission_classes=(permissions.IsAdminUser,),
Optional können Sie der Dokumentationsausgabe Informationen darüber hinzufügen, welche Authentifizierungstypen für die API verwendet werden. Dies geschieht in der Datei settings.py.
SWAGGER_SETTINGS = { 'SECURITY_DEFINITIONS': { 'Basic': { 'type': 'basic' }, 'Bearer': { 'type': 'apiKey', 'name': 'Authorization', 'in': 'header' } } }
Jetzt können Sie mit der Implementierung eines Zugriffspunkts beginnen, um ein Token zu erhalten.
API-Anwendung
Lassen Sie uns eine API-Anwendung erstellen, in der ein Endpunkt hinzugefügt wird, um ein Token zu erhalten.
python manage.py startapp api
serializers.py
Als Nächstes erstellen wir eine Datei mit Serializern, in der ein spezieller Serializer erstellt wird, der die Antwort der Site in Swagger beschreibt.
# -*- coding: utf-8 -*- from rest_framework import serializers class Response201AuthTokenSerializer(serializers.Serializer): token = serializers.CharField(required=True, allow_blank=False) user_id = serializers.IntegerField(required=True)
Dieser Serializer generiert die Antwortinformationen in der Dokumentation korrekt und ich verwende ihn, um eine JSON-Antwort mit einem Token zu generieren.
views.py
Dann ändern wir die Datei views.py, um den Endpunkt zu erhalten.
# -*- coding: utf-8 -*- from django.contrib.auth import get_user_model from django.http import JsonResponse from django.utils.translation import gettext_lazy as _ from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema from rest_framework import authentication, viewsets from rest_framework.authtoken.views import ObtainAuthToken from api.serializers import Response201AuthTokenSerializer class CustomAuthToken(ObtainAuthToken): authentication_classes = [authentication.BasicAuthentication] @swagger_auto_schema(responses={ "201": openapi.Response( description=_("User has got Token"), schema=Response201AuthTokenSerializer, ) }) def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) response201 = Response201AuthTokenSerializer(data={"token": token.key, "user_id": user.pk}) response201.is_valid(raise_exception=True) return JsonResponse(response201.data)
Wie Sie im Code sehen können, gibt es ein benutzerdefiniertes Swagger-Schema für die 201-Antwort, der Inhalt wurde erstellt. Die korrekte Dokumentation wird vom Response201AuthTokenSerializer-Serializer generiert.
Unter anderem verwende ich den Response201AuthTokenSerializer, um eine Antwort mit einem Token sowie einer Benutzer-ID zu bilden. In Zukunft verwende ich die Benutzer-ID, um Daten in einer mobilen Anwendung zu manipulieren.
Eine Besonderheit dieser Ansicht ist, dass nur BasicAuthentication als Authentifizierung verwendet wird, dh der Benutzer erhält Zugriff auf diese Ansicht nur über Benutzername und Passwort. In Zukunft ist die API-Entwicklung im Gange, um das Token zu verwenden.
urls.py
Und jetzt verbinden Sie die Ansicht, um das Token in den URL-Dateien zu erhalten
# -*- coding: utf-8 -*- from django.urls import path from api import views app_name = 'api' urlpatterns = [ path('api-token-auth/', views.CustomAuthToken.as_view()), ]
In dieser Datei definieren wir den Namen der Anwendung, die zum Generieren von Routen verwendet wird, also api. Wir verbinden auch die Ansicht des Tokens mit dem Routing.
Und am Ende fügen wir die urls.py der API-Anwendung in die Hauptdatei urls.py des gesamten Projekts ein.
urlpatterns = [ ... path('api/', include('api.urls')), ... ]
Um nun ein Token zu erhalten, müssen Sie eine POST-Anfrage an die URL http://127.0.0.1/api/api-token-auth/ senden, wenn Sie die Funktionalität auf einem lokalen testen möchten Server. Im Falle eines Kampfservers müssen Sie eine Anfrage an die Adresse mit der Domain Ihrer Website senden.
Für die Authentifizierung müssen Sie die Standardauthentifizierung verwenden.
Beispiel einer Token-Anfrage in Felgo QML
Hier ist ein Beispielcode zum Anfordern eines Tokens in einer in QML Felgo geschriebenen Anwendung
function login(username, password, success, error) { HttpRequest .post("http://127.0.0.1/api/api-token-auth/", {username: username, password: password}) .timeout(5000) .set('Content-Type', 'application/json') .then(function(res) { success(res) }) .catch(function(err) { error(err) }); }
Доброго времени.
А если кастомный юзер.
И активация юзера подтверждением по смс или звонку?
Добрый день
Если Вы имеетe ввиду, что модель пользователя наследована от AbstractUser и переопределена для проекта, то да - этот пример рабочий, я сейчас занимаюсь одним проектом, который будет иметь приложение и использую там кастомного пользователя.
А что касается подтверждения по СМС, то я участвовал несколько лет назад в проекте, где было подтверждение по СМС. Код показать не могу, но суть была в том, что там было два REST API View, сначало приложение стучалось на первый url, куда посылало логин и пароль, при получении ответа 200, приложение меняло форму ввода данных и ждало, пока пользователь заполнит код из СМС и подтвердит отправку. В этом случае отправка кода была уже на второй url, который проверял правильность кода, и уже в этом случае отдавал токен.
Естественно первый URL, который обрабатывал логин и пароль, стучался на API стороннего провайдера по отправке СМС, получал отправленный код и сохранял в отдельную таблицу, чтобы потом сравнить код и соответствие пользователя коду.
В моем случае кастом от AbstractBaseUser
Только токен я использую knox(Стандарт мобильной безопастности Samsung), потому и спросил
Дальше понятно:
Регистрация post на страницу урл api/register(можно сразу отправить запрос на звонок, после создания пользователя)
Если удачно то получим 4-x символьный код от провайдера, запищем его. Если неудачно то создаем свой и шлем смс
Cледом post-запрос на верификацию с кодом(при удаче - активируем пользователя, при не удаче 4 попытки на повтор)
В таком случае без напильника этот код сходу не взлетит, если конкретно knox нужно использовать.
А касательно самого AbstractBaseUser, то должно заработать.