Denne opplæringen vil gi en introduksjon til JSON Web Tokens (JWT) og hvordan du implementerer JWT-godkjenning i Django.
JWT er en kodet JSON-streng som er sendt i overskrifter for å godkjenne forespørsler. Det oppnås vanligvis ved haksing av JSON-data med en hemmelig nøkkel. Dette betyr at serveren ikke trenger å spørre databasen hver gang for å hente brukeren tilknyttet et gitt token.
Når en bruker logger på med å bruke sine legitimasjonsbeskrivelser, oppnås en JSON Web Token og lagres i lokal lagring. Når brukeren ønsker å få tilgang til en beskyttet nettadresse, sendes token i overskriften til forespørselen. Serveren kontrollerer deretter for en gyldig JWT i autorisasjonsoverskriften, og hvis den er funnet, vil brukeren få tilgang.
En typisk innholdsoverskrift ser slik ut:
Tillatelse: Bearer eyJhbGciOiJIUzI1NiIsI
Nedenfor er et diagram som viser denne prosessen:
Autentisering er prosessen med å identifisere en innlogget bruker, mens autorisasjon er prosessen med å identifisere om en bestemt bruker har rett til å få tilgang til en nettressurs.
I denne opplæringen skal vi bygge et enkelt brukerautentiseringssystem i Django ved hjelp av JWT som godkjenningsmekanisme.
La oss komme i gang.
Opprett en katalog hvor du vil beholde prosjektet ditt og også et virtuelt miljø for å installere prosjektets avhengigheter.
mkdir myprojects cd myprojects virtuell venv
Aktiver det virtuelle miljøet:
kilde venv / bin / aktiver
Lag et Django-prosjekt.
django-admin startprosjekt django_auth
Installer DRF og django-rest-framework-jwt ved hjelp av pip.
pip installere djangorestframework pip installere djangorestframework-jwt pip installere django
La oss gå videre og legge til DRF i listen over installerte apper i settings.py
fil.
For å kunne bruke JWT må vi konfigurere django-rest-rammebetingelser for å godta JSON Web Tokens.
I settings.py
fil, legg til følgende konfigurasjoner:
REST_FRAMEWORK = 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_jwt.authentication.JSONWebTokenAuthentication',),,
Opprett en ny app som heter brukere som håndterer brukergodkjenning og -administrasjon.
cd django-auth django-admin.py startapp-brukere
Legg til brukerprogrammet til listen over installerte apper i settings.py
fil.
Vi skal bruke PostgreSQL-databasen fordi den er mer stabil og robust.
Opprett auth
database og tilordne en bruker.
Bytt til Postgres-kontoen på maskinen din ved å skrive:
sudo su postgres
Få tilgang til Postgres-spørringen og opprett databasen:
psql postgres = # CREATE DATABASE auth;
Lag en rolle:
postgres = # CREATE ROLE django_auth MED LOGG INN PASSWORD 'asdfgh';
Gi tilgang til databasen til brukeren:
postgres = # TILSTILL ALLE PRIVILEGER PÅ DATABASSE AUTH TIL django_auth;
Installer psycopg2-pakken, som vil tillate oss å bruke databasen vi konfigurerte:
pip installere psycopg2
Rediger den nåværende konfigurerte SQLite-databasen og bruk Postgres-databasen.
DATABASES = 'default': 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'auth', 'BRUKER': 'django_auth', 'PASSWORD': 'asdfgh', 'HOST' 'localhost', 'port': ",
Django kommer med et innebygd autentiseringssystem som er svært forseggjort, men noen ganger må vi gjøre justeringer, og dermed må vi lage et egendefinert brukerautentiseringssystem. Vår brukermodell vil arve fra AbstractBaseUser
klasse levert av django.contrib.auth.models
.
I brukere / models.py starter vi ved å opprette brukermodellen for å lagre brukeropplysningene.
# users / models.py fra __future__ importere unicode_literals fra django.db importmodeller fra django.utils importere tidszone fra django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin) klasse Bruker (AbstractBaseUser, PermissionsMixin): "" "En abstrakt base klassen implementerer en fullverdig brukermodell med administratorkompetente tillatelser. "" "email = models.EmailField (max_length = 40, unikt = True) first_name = models.CharField (max_length = 30, blank = True) last_name = models.CharField max_length = 30, blank = True) is_active = models.BooleanField (standard = True) is_staff = models.BooleanField (default = False) date_joined = models.DateTimeField (default = timezone.now) objekter = UserManager () USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['first_name', 'last_name'] def lagre (selv, * args, ** kwargs): super (bruker, selv) .save (* args, ** kwargs) returnere selv
OBLIGATORISKE FELT
inneholder alle nødvendige felt på brukermodellen din, unntatt brukernavn og passord, da disse feltene alltid blir bedt om.
UserManager
er klassen som definerer Opprett bruker
og createsuperuser
metoder. Denne klassen skal komme før AbstractBaseUser
klasse vi definerte ovenfor. La oss gå videre og definere det.
fra django.contrib.auth.models importerer (AbstractBaseUser, PermissionsMixin, BaseUserManager) klassen UserManager (BaseUserManager): def _create_user (selv, e-post, passord, ** extra_fields): "" "Oppretter og lagrer en bruker med den oppgitte e-postadressen, og passord. "" "Hvis ikke e-post: øk ValueError ('Den oppgitte e-postadressen må settes') Prøv: med transaction.atomic (): user = self.model (email = email, ** extra_fields) user.set_password user.save (using = self._db) returner bruker unntatt: heve def create_user (selv, e-post, passord = ingen, ** ekstra_felt): extra_fields.setdefault ('is_staff', False) extra_fields.setdefault ('is_superuser', False ) returner self._create_user (email, passord, ** extra_fields) def create_superuser (selv, e-post, passord, ** ekstra_felt): extra_fields.setdefault ('is_staff', True) extra_fields.setdefault ('is_superuser', True) returnerer selv ._create_user (email, passord = passord, ** ekstra_fields)
Overføringer gir deg mulighet til å oppdatere databaseskjemaet hver gang modellene dine endres uten å miste data.
Opprett en innledende migrering for brukerens modell, og synkroniser databasen for første gang.
python manage.py gjør migranter brukere python manage.py migrere
Opprett en superbruker ved å kjøre følgende kommando:
python manage.py skaperupperuser
La oss lage et sluttpunkt for å aktivere registrering av nye brukere. Vi starter med å serialisere brukermodellfeltene. Serializers gir en måte å endre data til et skjema som er lettere å forstå, som JSON eller XML. Deserialisering gjør det motsatte, som konverterer data til et skjema som kan lagres i databasen.
Opprett brukere / serializers.py og legg til følgende kode.
# brukere / serializers.py fra rest_framework import serializers from.models import Bruker klasse UserSerializer (serializers.ModelSerializer): date_joined = serializers.ReadOnlyField () klasse Meta (objekt): model = Brukerfelt = ('id', 'email' 'first_name', 'last_name', 'date_joined', 'password') ekstra_kwargs = 'passord': 'write_only': True
Deretter ønsker vi å opprette en visning slik at klienten vil ha en nettadresse for å opprette nye brukere.
I users.views.py, legg til følgende:
# brukere / views.py klasse CreateUserAPIView (APIView): # Tillat noen bruker (godkjent eller ikke) å få tilgang til denne URLen permission_classes = (AllowAny,) def post (selv, forespørsel): user = request.data serializer = UserSerializer (data = bruker) serializer.is_valid (raise_exception = True) serializer.save () returnere Response (serializer.data, status = status.HTTP_201_CREATED)
Vi setter permission_classes
til (AllowAny,)
for å tillate noen bruker (godkjent eller ikke) å få tilgang til denne nettadressen.
Lag en fil brukere / urls.py
og legg til nettadressen for å matche visningen vi opprettet. Legg også til følgende kode.
# users / urls.py fra django.conf.urls import url, mønstre fra .views import CreateUserAPIView urlpatterns = [url (r '^ opprett / $', CreateUserAPIView.as_view ()),]
Vi må også importere nettadresser fra brukerprogrammet til hovedlisten django_auth / urls.py
fil. Så gå videre og gjør det. Vi bruker inkludere
Funger her, så ikke glem å importere den.
# django_auth / urls.py fra django.conf.urls import url, inkludere fra django.contrib import admin urlpatterns = [url (r '^ admin /', admin.site.urls), url (r '^ user /', inkludere ('users.urls', namespace = "brukere")),]
Nå som vi er ferdige med å skape endepunktet, la oss gjøre en test og se om vi er på sporet. Vi vil bruke Postman til å gjøre testene. Hvis du ikke er kjent med Postman, er det et verktøy som presenterer en vennlig GUI for å bygge forespørsler og lese svar.
Som du kan se over, fungerer endepunktet som forventet.
Vi vil gjøre bruk av Django-REST Framework JWT Python modulen vi installerte i begynnelsen av denne opplæringen. Den legger til JWT-godkjenningsstøtte for Django Rest Framework-apper.
Men først, la oss definere noen konfigurasjonsparametere for våre tokens og hvordan de genereres i settings.py-filen.
# settings.py import datetime JWT_AUTH = 'JWT_VERIFY': True, 'JWT_VERIFY_EXPIRATION': True, 'JWT_EXPIRATION_DELTA': datetime.timedelta (sekunder = 3000), 'JWT_AUTH_HEADER_PREFIX': 'bærer',
JWT_VERIFY
: Det vil hente en jwt.DecodeError hvis hemmeligheten er feil.JWT_VERIFY_EXPIRATION
: Angir utløpet til True, som betyr at Tokene utløper etter en tidsperiode. Standardtiden er fem minutter.JWT_AUTH_HEADER_PREFIX
: Autorisasjonsheader-verdi prefiksen som skal sendes sammen med symbolet. Vi har satt det som bærer
, og standard er JWT
.I brukere / views.py
, legg til følgende kode.
@api_view (['POST']) @permission_classes ([AllowAny,]) def authenticate_user (forespørsel): prøv: email = request.data ['email'] passord = request.data ['password'] user = User.objects .get (email = email, passord = passord) hvis bruker: prøv: payload = jwt_payload_handler (bruker) token = jwt.encode (nyttelast, settings.SECRET_KEY) user_details = user_details ['name'] = "% s% s "% (user.first_name, user.last_name) user_details ['token'] = token user_logged_in.send (sender = bruker .__ class__, request = request, user = bruker) returnere Svar (user_details, status = status.HTTP_200_OK) unntatt Unntak som e: heve e else: res = 'error': 'kan ikke autentisere med de oppgitte legitimasjonene eller kontoen har blitt deaktivert' returnere Response (res, status = status.HTTP_403_FORBIDDEN) unntatt KeyError: res = 'error' : 'vennligst oppgi e-post og passord' returnere svar (res)
I koden ovenfor tar påloggingsvisningen brukernavn og passord som input, og det oppretter deretter et token med brukerinformasjonen som svarer til de bestått legitimasjonene som nyttelast og returnerer den til nettleseren. Andre brukerdetaljer som navn returneres også til nettleseren sammen med token. Denne token vil bli brukt til å godkjenne i fremtidige forespørsler.
Tillatelsesklassene er satt til allowAny
siden alle kan få tilgang til dette sluttpunktet.
Vi lagrer også brukerens siste innloggetid med denne koden.
user_logged_in.send (sender = bruker .__ class__, request = request, user = user)
Hver gang brukeren ønsker å gjøre en API-forespørsel, må de sende token i Auth Headers for å godkjenne forespørselen.
La oss teste dette sluttpunktet med Postman. Åpne Postman og bruk forespørselen til å autentisere med en av brukerne du opprettet tidligere. Hvis påloggingsforsøket er vellykket, vil svaret se slik ut:
Så langt kan brukerne registrere og autentisere seg selv. Men de trenger også en måte å hente og oppdatere sin informasjon på. La oss implementere dette.
I users.views.py
, legg til følgende kode.
class UserRetrieveUpdateAPIView (RetrieveUpdateAPIView): # Tillat bare autentiserte brukere å få tilgang til denne URLen permission_classes = (IsAuthenticated,) serializer_class = UserSerializer def get (selv, forespørsel, * args, ** kwargs): # serializer som håndterer å snu våre 'User' noe som # kan bli JSONified og sendt til klienten. serializer = self.serializer_class (request.user) return Response (serializer.data, status = status.HTTP_200_OK) def put (selv, forespørsel, * args, ** kwargs): serializer_data = request.data.get ('bruker' (serializer.data, status = status.HTTP_200_OK) serializer = UserSerializer (request.user, data = serializer_data, partial = True) serializer.is_valid (raise_exception = True) serializer.save
Vi definerer først tillatelsesklassene og settes til IsAuthenticated
siden dette er en beskyttet nettadresse, og bare autentiserte brukere kan få tilgang til det.
Vi definerer da en få
metode for å hente brukerdetaljer. Etter å ha hentet brukerdetaljer, vil en godkjent bruker deretter oppdatere sine opplysninger etter behov.
Oppdater nettadressene dine for å definere endepunktet som følger.
brukere / urls.py fra .views import CreateUserAPIView, UserRetrieveUpdateAPIView urlpatterns = [url (r '^ oppdatering / $', UserRetrieveUpdateAPIView.as_view ()),]
For at forespørselen skal lykkes, skal overskriftene inneholde JWT-token som vist nedenfor.
Hvis du prøver å be om en ressurs uten autentiseringsoverskriften, får du følgende feil.
Hvis en bruker forblir lenger enn den angitte tiden i JWT_EXPIRATION_DELTA
uten å gjøre en forespørsel, vil symbolet utløpe og de må be om et annet token. Dette er også demonstrert nedenfor.
Denne opplæringen har dekket det som er nødvendig for å kunne bygge et solid back-end-godkjenningssystem med JSON Web Tokens.