Acest tutorial va oferi o introducere în JSON Web Tokens (JWT) și modul de implementare a autentificării JWT în Django.
JWT este un șir JSON codificat care este trecut în anteturi pentru a autentifica cererile. Acesta este de obicei obținut prin ștergerea datelor JSON cu o cheie secretă. Acest lucru înseamnă că serverul nu are nevoie să interogheze baza de date de fiecare dată pentru a prelua utilizatorul asociat cu un anumit jeton.
Atunci când un utilizator se conectează cu succes utilizând datele de identificare, un JSON Web Token este obținut și salvat în spațiul de stocare local. Ori de câte ori utilizatorul dorește să acceseze o adresă URL protejată, simbolul este trimis în antetul solicitării. Serverul verifică apoi un JWT valid în antetul de autorizare și dacă este găsit, utilizatorul va avea acces.
Un antet tipic de conținut va arăta astfel:
Autorizație: purtător eyJhbGciOiJIUzIlIIsI
Mai jos este o diagramă care arată acest proces:
Autentificarea este procesul de identificare a unui utilizator logat, în timp ce autorizarea este procesul de identificare a faptului dacă un anumit utilizator are dreptul de a accesa o resursă web.
În acest tutorial, vom construi un sistem simplu de autentificare a utilizatorilor în Django folosind JWT ca mecanism de autentificare.
Să începem.
Creați un director unde veți păstra proiectul și, de asemenea, un mediu virtual pentru a instala dependențele proiectului.
mkdir myprojects cd myprojects virtual venv
Activați mediul virtual:
sursa venv / bin / activare
Creați un proiect Django.
django-admin startproject django_auth
Instalați DRF și django-rest-framework-jwt folosind pip.
pip instalare djangorestframework pip instalare djangorestframework-jwt pip instalare django
Să mergem mai departe și să adăugăm DRF la lista de aplicații instalate în settings.py
fişier.
Pentru a utiliza JWT, trebuie să configurați permisiunile django-rest-framework pentru a accepta JSON Web Tokens.
În settings.py
fișier, adăugați următoarele configurații:
REST_FRAMEWORK = 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_jwt.authentication.JSONWebTokenAuthentication',),
Creați o nouă aplicație numită utilizatori care va gestiona autentificarea și gestionarea utilizatorilor.
cd django-auth django-admin.py utilizatorilor startapp
Adăugați aplicația pentru utilizatori în lista aplicațiilor instalate din settings.py
fişier.
Vom folosi baza de date PostgreSQL deoarece este mai stabilă și mai robustă.
Creați AUTH
bază de date și să atribuiți un utilizator.
Treceți la contul Postgres al mașinii tastând:
sudo su postgres
Accesați promptul Postgres și creați baza de date:
psql postgres = # CREATE DATABASE auth;
Creați un rol:
postgres = # CREATE ROLE django_auth CU LOGIN PASSWORD 'asdfgh';
Acordați acces la baza de date pentru utilizator:
postgres = # GRANTA TOATE PRIVILEGIILE PE DATABASE auth TO django_auth;
Instalați pachetul psycopg2, care ne va permite să folosim baza de date pe care am configurat-o:
pip instalează psycopg2
Editați baza de date SQLite configurată și utilizați baza de date Postgres.
DATABASES = 'default': 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'auth', 'USER': 'django_auth', 'PASSWORD': 'asdfgh', 'HOST': 'localhost', 'PORT': ",
Django vine cu un sistem de autentificare încorporat, care este foarte elaborat, dar uneori trebuie să facem ajustări și, prin urmare, trebuie să creăm un sistem personalizat de autentificare a utilizatorilor. Modelul nostru de utilizator va moșteni de la AbstractBaseUser
clasa furnizată de django.contrib.auth.models
.
În utilizatori / models.py, începem prin crearea modelului de utilizator pentru a stoca detaliile utilizatorului.
# users / models.py from __future__ importați unicode_literals din modelele de import django.db din fusul orar de import django.utils din importul (abstractBaseUser, PermissionsMixin) ("max_length = 40, unic = adevărat") first_name = models.CharField (max_length = 30, blank = True) last_name = models.CharField ( max_length = 30, blank = Adevărat) is_active = models.BooleanField (implicit = True) is_staff = models.BooleanField (implicit = False) date_joined = models.DateTimeField (USERNAME_FIELD = REQUIRED_FIELDS = ['first_name', 'last_name'] def save (auto, * args, ** kwargs): super (User, self) .save (* args, ** kwargs)
CÂMPURI OBLIGATORII
conține toate câmpurile necesare pe modelul dvs. de utilizator, cu excepția câmpului de utilizator și a parolei, deoarece aceste câmpuri vor fi întotdeauna solicitate.
UserManager
este clasa care definește creaza utilizator
și createsuperuser
metode. Această clasă ar trebui să vină în fața AbstractBaseUser
clasa pe care am definit-o mai sus. Să mergem mai departe și să o definim.
de la django.contrib.auth.models Import (AbstractBaseUser, PermissionsMixin, BaseUserManager) clasa UserManager (BaseUserManager): def _create_user (auto, email, parola, ** extra_fields): "" Crează și salvează un Utilizator cu e-mailul dat și parola "" "dacă nu e-mail: ridicați ValueError ('Adresa de email dată trebuie să fie setată') încercați: cu transaction.atomic (): user = self.model user.set_password (password) user_savat (foloseste = auto._db) returneaza userul cu exceptia: raise def create_user (sine, email, parola = Niciuna, ** extra_fields): extra_fields.setdefault ('is_staff', False) extra_fields.setdefault ) întoarcere self__create_user (e-mail, parola, ** extra_fields) def create_superuser (auto, email, parola, ** extra_fields): extra_fields.setdefault ('is_staff', True) ._create_user (email, parola = parola, ** extra_fields)
Migrările oferă o modalitate de actualizare a schemelor de bază de date de fiecare dată când modelele se modifică, fără a pierde date.
Creați o migrare inițială pentru modelul utilizatorilor noștri și sincronizați baza de date pentru prima dată.
python manage.py a face migrații utilizatorii să migreze python manage.py
Creați un superuser executând următoarea comandă:
python manage.py createsuperuser
Să creați un punct final pentru a permite înregistrarea noilor utilizatori. Vom începe prin serializarea câmpurilor modelului Utilizator. Serializatorii oferă o modalitate de schimbare a datelor într-o formă mai ușor de înțeles, cum ar fi JSON sau XML. Deserializarea face opusul, care convertește datele într-o formă care poate fi salvată în baza de date.
Creați utilizatori / serializers.py și adăugați următorul cod.
# users / serializers.py de la rest_framework import serializers from.models import Clasa utilizator UserSerializer (serializers.ModelSerializer): date_joined = serializers.ReadOnlyField () clasa Meta (object): model = User fields = ('id', ' 'first_name', 'last_name', 'date_joined', 'parola') extra_kwargs = 'password': 'write_only': True
Apoi, dorim să creăm o vizualizare, astfel încât clientul să aibă o adresă URL pentru crearea de noi utilizatori.
În users.views.py, adăugați următoarele:
# users / views.py clasă CreateUserAPIView (APIView): # Permite oricărui utilizator (autentificat sau nu) să acceseze această adresă url permission_classes = (AllowAny,) def post (auto, cerere): user = request.data serializer = UserSerializer (data = utilizator) serializer.is_valid (raise_exception = adevărat) serializer.save () return Response (serializer.data, status = status.HTTP_201_CREATED)
Noi am stabilit permission_classes
la (AllowAny,)
pentru a permite oricărui utilizator (autentificat sau nu) să acceseze această adresă URL.
Creați un fișier utilizatorii / urls.py
și adăugați adresa URL pentru a se potrivi cu vizualizarea pe care am creat-o. Adăugați, de asemenea, următorul cod.
# users / urls.py de la adresa django.conf.urls import url, modele din importul .views CreateUserAPIView urlpatterns = [url (r '^ create / $', CreateUserAPIView.as_view ()),]
De asemenea, trebuie să importem adrese URL din aplicația utilizatorilor în principal django_auth / urls.py
fişier. Așa că mergeți și faceți asta. Noi folosim include
funcționați aici, deci nu uitați să le importați.
# django_auth / urls.py de la adresa de import django.conf.urls, includeți de la django.contrib importul admin urlpatterns = [url (r '^ admin /', admin.site.urls), url (r '^ user / include ("users.urls", namespace = "users")),]
Acum, când am terminat de creat punctul final, să facem un test și să vedem dacă suntem pe drumul cel bun. Vom folosi postmanul pentru a face testele. Dacă nu sunteți familiarizați cu Postman, este un instrument care prezintă un GUI prietenos pentru construirea de cereri și răspunsuri la lectură.
După cum puteți vedea mai sus, punctul final funcționează conform așteptărilor.
Vom folosi modulul Python JWT-cadru Django-REST pe care l-am instalat la începutul acestui tutorial. Acesta adaugă suport pentru autentificarea JWT pentru aplicațiile Django Rest Framework.
Dar mai întâi, să definim câțiva parametri de configurare pentru token-urile noastre și cum sunt generate în fișierul settings.py.
# setări calendar datetime importare JWT_AUTH = 'JWT_VERIFY': Adevărat, 'JWT_VERIFY_EXPIRATION': Adevărat 'JWT_EXPIRATION_DELTA': datetime.timedelta (secunde = 3000), 'JWT_AUTH_HEADER_PREFIX'
JWT_VERIFY
: Se va ridica un jwt.DecodeError dacă secretul este greșit.JWT_VERIFY_EXPIRATION
: Seteaza expirarea la True, inseamna ca Tokens va expira dupa o perioada de timp. Timpul prestabilit este de cinci minute.JWT_AUTH_HEADER_PREFIX
: Prefixul valorii headerului autorizației care trebuie trimis împreună cu jetonul. Am stabilit ca Purtător
, și implicit este JWT
.În utilizatorii / views.py
, adăugați următorul cod.
@api_view (['POST']) @permission_classes ([AllowAny,]) def authenticate_user (request): încercați: email = request.data ['email'] password = request.data ['password'] user = User.objects .get (e-mail, parola = parola) dacă utilizatorul: try: payload = jwt_payload_handler (utilizator) token = jwt.encode (payload, settings.SECRET_KEY) user_details = user_details ['name'] = "% s% s "user_details ['token'] = token user_logged_in.send (sender = user .__ class__, request = request, user = user) return Response (user_details, status = status.HTTP_200_OK) (res = status = status.HTTP_403_FORBIDDEN) cu excepția KeyError: res = 'error' = ' : "vă rugăm să furnizați un e-mail și o parolă" return Response (res)
În codul de mai sus, vizualizarea de autentificare are numele de utilizator și parola ca intrare și apoi creează un jeton cu informațiile despre utilizator care corespund acreditărilor date ca încărcătură utilă și îl returnează browserului. Alte informații despre utilizator, cum ar fi numele, sunt de asemenea returnate browserului împreună cu jetonul. Acest jeton va fi folosit pentru autentificarea în cererile viitoare.
Clasele de permisiune sunt setate la allowAny
deoarece oricine poate accesa acest obiectiv.
De asemenea, stocăm ultima dată de conectare a utilizatorului cu acest cod.
user_logged_in.send (sender = user .__ class__, request = request, user = user)
De fiecare dată când utilizatorul dorește să facă o solicitare API, trebuie să trimită jetonul în Anteturi Auth pentru a autentifica cererea.
Să testăm acest punct final cu Postman. Deschideți poștașul și utilizați solicitarea de autentificare cu unul dintre utilizatorii pe care i-ați creat anterior. Dacă încercarea de conectare are succes, răspunsul va arăta astfel:
Până în prezent, utilizatorii se pot înregistra și autentifica singuri. Cu toate acestea, ei au nevoie și de o modalitate de a-și recupera și actualiza informațiile. Să implementăm acest lucru.
În users.views.py
, adăugați următorul cod.
class = UserArticleSerieserUpdateAPIView (RetrieveUpdateAPIView): # Permite doar accesul utilizatorilor autentificați la această adresă URL permission_classes = (IsAuthenticated, serializer_class = UserSerializer def get (self, request, args, ** kwargs) ceva ce # poate fi JSONified și trimis clientului. serializer = auto.serializer_class (request.user) retur Răspundere (serializer.data, status = status.HTTP_200_OK) def (self, request, args, kwargs) serializer_data = request.data.get serializer = UserSerializer (request.user, data = serializer_data, partial = True) serializer.is_valid (raise_exception = True) serializer.save () return Response (serializer.data, status = status.HTTP_200_OK)
Mai întâi definim clasele de permisiune și setăm la IsAuthenticated
deoarece aceasta este o adresă URL protejată și numai utilizatorii autentificați pot accesa aceasta.
Apoi definim a obține
metodă de recuperare a detaliilor utilizatorului. După preluarea detaliilor utilizatorului, un utilizator autentificat își va actualiza detaliile după cum doriți.
Actualizați adresele URL pentru a defini punctul final după cum urmează.
utilizatorii / urls.py de la importul .views CreateUserAPIView, UserRetrieveUpdateAPIView urlpatterns = [url (r '^ update / $', UserRetrieveUpdateAPIView.as_view ()),]
Pentru ca cererea să aibă succes, antetele ar trebui să conțină indicativul JWT, după cum se arată mai jos.
Dacă încercați să solicitați o resursă fără antetul de autentificare, veți primi următoarea eroare.
Dacă un utilizator rămâne în afara timpului specificat în JWT_EXPIRATION_DELTA
fără a face o cerere, tokenul va expira și vor trebui să solicite un alt simbol. Acest lucru este demonstrat, de asemenea, mai jos.
Acest tutorial a acoperit ceea ce este necesar pentru a construi cu succes un sistem solid de autentificare back-end cu JSON Web Tokens.