bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


django_ninja

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
django_ninja [2025/02/05 22:58]
enric_mieza_sanchez [Autenticació]
django_ninja [2025/03/21 16:18] (actual)
enric_mieza_sanchez [Autenticació]
Línia 24: Línia 24:
  
 Destaquem dos mètodes d'autenticació molt estandarditzats: Destaquem dos mètodes d'autenticació molt estandarditzats:
-  * **Basic Authentication** : amb usuari i contrasenya. Convé no fer-la servir sovint ja que la contrasenya és una dada sensible. La clàssica crida a un endpoint amb aquest mecanisme seria:<code bash>curl http://localhost:8000/api/token/ -u manolo:pass123 -X POST</code>+  * **Basic Authentication** : amb usuari i contrasenya. Convé no fer-la servir sovint ja que la contrasenya és una dada sensible. La clàssica crida a un endpoint amb aquest mecanisme seria:<code bash>curl http://localhost:8000/api/token/ -u manolo:pass123</code>
   * **Token Authentication** : millora la seguretat en les crides a l'API, enviant un //token// enlloc de la contrasenya. El //token// es pot obtenir, per exemple, per Basic Authentication. Les crides a l'API s'han d'acompanyar del //token// sempre, i es pot fer de diverses formes de la qual destaquem el //header Bearer//:<WRAP prewrap><code bash>curl -H 'Authorization: Bearer 1d895b9062512a731b1e5667bd034da3' http://localhost:8000/api/llibres</code></WRAP>   * **Token Authentication** : millora la seguretat en les crides a l'API, enviant un //token// enlloc de la contrasenya. El //token// es pot obtenir, per exemple, per Basic Authentication. Les crides a l'API s'han d'acompanyar del //token// sempre, i es pot fer de diverses formes de la qual destaquem el //header Bearer//:<WRAP prewrap><code bash>curl -H 'Authorization: Bearer 1d895b9062512a731b1e5667bd034da3' http://localhost:8000/api/llibres</code></WRAP>
  
Línia 30: Línia 30:
  
 <code python api.py> <code python api.py>
-from django.contrib.auth import authenticate+from django.contrib.auth import authenticate as django_authenticate
 from ninja import NinjaAPI, Schema from ninja import NinjaAPI, Schema
 from ninja.security import HttpBasicAuth, HttpBearer from ninja.security import HttpBasicAuth, HttpBearer
-from typing import List+from typing import List, Optional
 from .models import * from .models import *
 import secrets import secrets
Línia 42: Línia 42:
 class BasicAuth(HttpBasicAuth): class BasicAuth(HttpBasicAuth):
     def authenticate(self, request, username, password):     def authenticate(self, request, username, password):
-        user = authenticate(username=username, password=password)+        user = django_authenticate(username=username, password=password)
         if user:         if user:
             # Genera un token simple             # Genera un token simple
Línia 61: Línia 61:
  
 # Endpoint per obtenir un token, accés amb BasicAuth # Endpoint per obtenir un token, accés amb BasicAuth
-@api.post("/token/", auth=BasicAuth())+# amb o sense "trailing slash" 
 +@api.get("/token", auth=BasicAuth()) 
 +@api.get("/token/", auth=BasicAuth())
 def obtenir_token(request): def obtenir_token(request):
     return {"token": request.auth}     return {"token": request.auth}
Línia 69: Línia 71:
     id: int     id: int
     titol: str     titol: str
-    editorial: str+    editorial: Optional[str]
  
-@api.get("/llibres", response=List[LlibreOut], auth=AuthBearer())+@api.get("/llibres/", response=List[LlibreOut], auth=AuthBearer())
 def get_llibres(request): def get_llibres(request):
     qs = Llibre.objects.all()     qs = Llibre.objects.all()
Línia 90: Línia 92:
  
 <code python settings.py> <code python settings.py>
-AUTH_USER_MODEL = 'biblio.Usuari'+AUTH_USER_MODEL = 'myapp.Usuari'
 </code> </code>
  
 +Per tal que els canvis es guardin a la base de dades caldrà crear i executar les migracions adequades:
 +
 +  (env) $ ./manage.py makemigrations
 +  (env) $ ./manage.py migrate
 +
 +<WRAP important>
 +Afegir canvis en el model d'usuari quan un projecte ja té dades de producció és problemàtic, com a mínim. **Es recomana sempre crear un model d'usuari personalitzat** (derivat d'AbstractUser) **des del principi del projecte** per poder afegir funcionalitats com aquesta (afegir token a l'usuari) quan sigui necessari.
 +
 +Si no tenim dades de producció, el més fàcil és esborrar la base de dades, esborrar tots els arxius de migració, i tornar a crear-los amb:
 +
 +  (env) $ ./manage.py makemigrations <nom_app>
 +
 +Una possible alternativa, per tal de no haver de crear un model d'usuari personalitzat, és crear una taula de tokens a part, i relacionar-la amb el ''User'' estàndard de Django. Igualment es sol recomanar prioritàriament particularitzar el model d'usuari,  ja que les situacions en les que interessarà ampliar-lo son molt comunes.
 +</WRAP>
  
 \\ \\
 +
 +===== Mes curl =====
 +
 +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 [[https://jqlang.org/tutorial/|utilitat jq]]
 +  curl -u admin:admin123 http://localhost:8000/api/users/ | jq
 +
 +Per instal·lar jq es pot fer:
 +  sudo apt install jq
  
django_ninja.1738796296.txt.gz · Darrera modificació: 2025/02/05 22:58 per enric_mieza_sanchez