Django Ninja és una llibreria per a fer APIs alternativa a la clàssica Django REST Framework (que podeu veure a l'article Django API) i fortament inspirada en la molt adoptada recentment FastAPI.
El principal avantatge és certa simplicitat per crear els endpoints.
Referències:
És relativament fàcil acostar-se a Django Ninja amb la seva documentació:
api.py
: https://django-ninja.dev/tutorial/
Destaquem dos mètodes d'autenticació molt estandarditzats:
curl http://localhost:8000/api/token/ -u manolo:pass123
curl -H 'Authorization: Bearer 1d895b9062512a731b1e5667bd034da3' http://localhost:8000/api/llibres
Es poden implementar les dues amb aquest codi:
from django.contrib.auth import authenticate from ninja import NinjaAPI, Schema from ninja.security import HttpBasicAuth, HttpBearer from typing import List, Optional from .models import * import secrets api = NinjaAPI() # Autenticació bàsica class BasicAuth(HttpBasicAuth): def authenticate(self, request, username, password): user = authenticate(username=username, password=password) if user: # Genera un token simple token = secrets.token_hex(16) user.auth_token = token user.save() return token return None # Autenticació per Token Bearer class AuthBearer(HttpBearer): def authenticate(self, request, token): try: user = Usuari.objects.get(auth_token=token) return user except Usuari.DoesNotExist: return None # Endpoint per obtenir un token, accés amb BasicAuth # amb o sense "trailing slash" @api.get("/token", auth=BasicAuth()) @api.get("/token/", auth=BasicAuth()) def obtenir_token(request): return {"token": request.auth} # Exemple d'endpoint per llistar els llibres, accés amb TokenAuth class LlibreOut(Schema): id: int titol: str editorial: Optional[str] @api.get("/llibres/", response=List[LlibreOut], auth=AuthBearer()) def get_llibres(request): qs = Llibre.objects.all() return qs
A part, també caldrà afegir la columna auth_token
al model Usuari
que cal personalitzar:
from django.contrib.auth.models import AbstractUser class Usuari(AbstractUser): auth_token = models.CharField(max_length=32,blank=True,null=True) # + altres atributs que es vulguin afegir...
I a settings.py
:
AUTH_USER_MODEL = 'myapp.Usuari'
El típic exemple de request amb Basic Authentication seria:
curl -u admin:admin123 http://localhost:8000/api/users/
De vegades ens pot interessar una alternativa enviant les dades codificades en base64 en els headers:
curl -H 'Authorization:Basic YWRtaW46YWRtaW4xMjM=' http://localhost:8000/api/users/
Per obtenir el hash en base64 es pot fer:
echo -n "admin:admin123" | base64
Per aconseguir un pretty print del JSON es pot fer amb la utilitat jq
curl -u admin:admin123 http://localhost:8000/api/users/ | jq
Per instal·lar jq es pot fer:
sudo apt install jq