bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


django_ninja

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 23:37]
enric_mieza_sanchez [Autenticació]
django_ninja [2026/04/09 16:01] (actual)
enric_mieza_sanchez [CORS : cridar l'API des de dominis creuats]
Línia 4: Línia 4:
  
 El principal avantatge és certa simplicitat per crear els endpoints. El principal avantatge és certa simplicitat per crear els endpoints.
 +
 +{{ django:django_vs_ninja.png?400 }}
  
 Referències: Referències:
Línia 30: Línia 32:
  
 <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
Línia 42: Línia 44:
 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 79: Línia 81:
 </code> </code>
  
-A parttambé caldrà afegir la columna ''auth_token'' al model ''Usuari'' que cal personalitzar:+\\ 
 + 
 +==== Ampliació del model d'usuari ==== 
 + 
 +Per tal que la Token Auth funcioniens caldrà que l'usuari emmagatzemi els //tokens// en algun lloc. 
 + 
 +Es pot fer de diverses maneres, una d'elles és afegir la columna ''auth_token'' al model ''Usuari'' que cal personalitzar, derivant de ''AbstractUser''.  
 + 
 +Ull, perquè aquest canvi tindrà implicacions profundes i ens obligarà a esborrar la base de dades i recomençar l'historial de migracions. Ho veurem mes tard. 
 + 
 +Comencem per canviar el model d'usuari i el redefinim a ''models.py'':
  
 <code python models.py> <code python models.py>
Línia 89: Línia 101:
 </code> </code>
  
-I a ''settings.py'':+I a ''settings.py'' (ULL, canviar <myapp> pel nom de la vostra app):
  
 <code python settings.py> <code python settings.py>
-AUTH_USER_MODEL = 'myapp.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
 +
 +Com que hem modificat l'usuari del sistema, ara no es visualitzarà a l'admin panel. Per visualitzar-lo correctament, apliqueu aquest ''UsuariAdmin'' a ''admin.py'':
 +
 +<file python admin.py>
 +from django.contrib import admin
 +from django.contrib.auth.admin import UserAdmin
 +
 +class UsuariAdmin(UserAdmin):
 +    fieldsets = UserAdmin.fieldsets + (
 +            ("Altres dades (API auth)", {
 +                'fields': ('auth_token',),
 +            }),
 +    )
 +    readonly_fields = ["auth_token",]
 +
 +admin.site.register(Usuari,UsuariAdmin)
 +</file>
 +
 +<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 i arxius de migracions**, i tornar a crear-los.
 +
 +  (env) $ rm db.sqlite3
 +  (env) $ rm -rf <myapp>/migrations
 +  (env) $ ./manage.py makemigrations <myapp>
 +  (env) $ ./manage.py migrate
 +
 +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
 +
 +\\
 +
 +===== CORS : cridar l'API des de dominis creuats =====
 +
 +Passa sovint que el desplegament d'una API és independent del //frontend//, on es pot utilitzar altres //frameworks// com React o AngularJS.
 +
 +Una mesura bàsica de seguretat és que el navegador web es negui a fer crides a APIs d'un altre dominis per evitar possibles injeccions de codi que treguin les nostres dades personals cap a dominis externs.
 +
 +Disposem d'una eina [[https://pypi.org/project/django-cors-headers/|Django CORS Headers]] amb la que podem avisar Django que hi ha determinats dominis que sí poden fer crides a l'API.
 +
 +  (env) $ pip install django-cors-headers
 +
 +Bàsicament caldrà instal·lar el plugin ''django-cors-headers'' i ajustar les variables a ''settings.py'':
 +  * ''INSTALLED_APPS'' : per activar el //plugin//
 +  * ''MIDDLEWARE'' : per processar totes les peticions a Django
 +  * ''CORS_ALLOWED_ORIGINS'' : llista de dominis que sí que poden accedir. Per ex. si utilitzem Vite per a React al //frontend//, hauriem de permetre http://localhost:5173 per treballar en development:<code>
 +CORS_ALLOWED_ORIGINS = [
 +    "http://localhost:5173",    # Exemple: React en desenvolupament amb Vite o CRA
 +    "http://127.0.0.1:5173",
 +    "https://el-teu-domini.com", # Quan el tinguis en producció
 +]</code>
 +
  
django_ninja.1738798664.txt.gz · Darrera modificació: 2025/02/05 23:37 per enric_mieza_sanchez