Қазіргі уақытта мен Django сайтының REST API интерфейсімен жұмыс істейтін қолданбада белсенді жұмыс істеп жатырмын. Алғашқы қадамдардың бірі пайдаланушы аутентификациясын токен арқылы орнату болды, бірақ бұл жұмыс істеуі үшін алдымен авторизация белгісін алу керек.
Мұны қалай жасауға болатынын қарастырайық.
Django Rest Framework орнату
Бұл DRF пайдалану туралы ең бірінші мақала болғандықтан, мен DRF орнату және конфигурациялау процесін толығырақ сипаттайтын боламын. Бұдан әрі мен бұл нұсқауларды бермеймін.
DRF және басқа қажетті бумаларды орнатыңыз
pip install djangorestframework pip install markdown # Markdown support for the browsable API. pip install django-filter
Әрі қарай, settings.py сайт конфигурация файлындағы INSTALLED_APPS қолданбасына "rest_frameword" қолданбасын қосыңыз.
INSTALLED_APPS = [ ... 'rest_framework', ]
Бұдан басқа, ресми құжаттама urls.py файлында rest_framework ішінен кіру және шығу көрінісін қосуды ұсынады, осылайша браузерде API интерфейсін ыңғайлы пайдалана аласыз.
Шынымды айтсам, мен бұл API қолданбаймын, өйткені мен үшін сваггер арқылы жасалған құжаттаманы пайдалану ыңғайлы, ол туралы кейінірек айтатын боламын, бірақ мен кездейсоқ мәселелерді шешпеу үшін View деректерін қосамын. кейінірек.
urlpatterns = [ ... path('api-auth/', include('rest_framework.urls')), ]
Содан кейін әдепкі аутентификация және рұқсат сыныптарын конфигурациялаңыз (сонымен қатар 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', ], }
Енді токенді алу үшін кіру нүктесін жазу үшін бәрі дайын. Бірақ алдымен мен генерацияланатын құжаттаманы байланыстырғым келеді. Бұл әдіспен жұмыс істеу ыңғайлырақ, мысалы, маған бәрі өте әдемі және ыңғайлы түрде көрсетілетін redoc құжаттамасы өте ұнайды.
Swagger орнатылуда
Енді біз сайтқа свагерді бірден қосамыз. Мен бұл мақаланың тақырыбына қатысты емес екенін түсінемін, бірақ кодта мен арнайы құжаттаманы көрсетуді қосу үшін арнайы манипуляциялар жасаймын және бұл болашақта сізге пайдалы болуы мүмкін деп ойлаймын, себебі:
- Болашақта свеггерді қолданасыз
- Кейде API сипаттамасындағы ақпараттың шығысын теңшеу қажет болады, атап айтқанда, менде сваггер үшін ең ерекше өзгеріс болған таңбалауыш үшін.
Мен drf-yasg орнатамын
Ол үшін құжаттамадан кейін келесі пәрменді іске қосыңыз
pip install -U drf-yasg
Содан кейін settings.py файлын өзгертеміз
INSTALLED_APPS = [ ... 'django.contrib.staticfiles', # required for serving swagger ui's css/js files 'drf_yasg', ... ]
Ал енді свагерді сайттың URL мекенжайларына тіркейік
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'), ]
Кодты мұқият қарап шықсаңыз, мен свеггерді тек сайт әкімшілігі үшін тіркегенімді көресіз. Құжаттаманың ашық болуын қаласаңыз, осы жолды алып тастаңыз
permission_classes=(permissions.IsAdminUser,),
Қосымша түрде құжаттаманың шығысына API үшін қандай аутентификация түрлері пайдаланылатыны туралы ақпаратты қосуға болады. Бұл settings.py файлында орындалады.
SWAGGER_SETTINGS = { 'SECURITY_DEFINITIONS': { 'Basic': { 'type': 'basic' }, 'Bearer': { 'type': 'apiKey', 'name': 'Authorization', 'in': 'header' } } }
Енді таңбалауышты алу үшін кіру нүктесін енгізуді бастауға болады.
Қолданбаның API
Токенді қабылдау үшін соңғы нүкте қосылатын api қолданбасын жасайық.
python manage.py startapp api
serializers.py
Әрі қарай, біз сериализаторлары бар файлды жасаймыз, онда арнайы сериализатор жасалатын болады, ол сайттың жауабын сваггерде сипаттайды.
# -*- 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)
Бұл сериализатор құжаттамадағы жауап ақпаратын дұрыс жасайды және мен оны таңбалауышпен JSON жауабын жасау үшін қолданамын.
views.py
Содан кейін соңғы нүктені алу үшін views.py файлын өзгертеміз.
# -*- 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)
Кодта көріп отырғаныңыздай, 201 жауабы үшін теңшелетін свеггер схемасы бар, мазмұн жасалды. Дұрыс құжаттама Response201AuthTokenSerializer сериализаторынан жасалады.
Басқа нәрселермен қатар мен Response201AuthTokenSerializer қолданбасын таңбалауышпен, сондай-ақ пайдаланушы идентификаторымен жауап қалыптастыру үшін пайдаланамын. Болашақта мен мобильді қосымшадағы деректерді өңдеу үшін пайдаланушы идентификаторын қолданамын.
Бұл көріністің ерекше нюансы түпнұсқалық растама ретінде тек BasicAuthentication пайдаланылады, яғни пайдаланушы бұл көрініске тек пайдаланушы аты мен құпия сөз арқылы қол жеткізе алады. Болашақта токенді пайдалану үшін API әзірленуде.
urls.py
Енді URL файлдарындағы таңбалауышты алу үшін көріністі қосыңыз
# -*- coding: utf-8 -*- from django.urls import path from api import views app_name = 'api' urlpatterns = [ path('api-token-auth/', views.CustomAuthToken.as_view()), ]
Бұл файлда біз маршруттарды жасау үшін қолданылатын қолданбаның атын анықтаймыз, яғни api. Маршрутизацияға маркердің көрінісін де қосамыз.
Соңында біз бүкіл жобаның негізгі urls.py файлына api қолданбасының urls.py файлын қосамыз.
urlpatterns = [ ... path('api/', include('api.urls')), ... ]
Енді токенді алу үшін http://127.0.0.1/api/api-token-auth/ url мекенжайына POST сұрауын жіберу керек, егер сіз жергілікті жерде функционалдылықты сынағыңыз келсе сервер. Жауынгерлік сервер жағдайында сіз өзіңіздің сайтыңыздың доменімен мекенжайға сұрау жіберуіңіз керек.
Аутентификация үшін негізгі аутентификацияны пайдалану қажет.
Felgo QML жүйесіндегі таңбалауыш сұрауының мысалы
Мұнда QML Felgo тілінде жазылған қолданбада таңбалауышты сұрауға арналған мысал коды берілген
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, то должно заработать.