Django runserver sobre https

Estos dos últimos meses he estado trabajando con una tienda virtual desarrollada con django llamada django oscar. Muy interesante el juguete, tunearla ha habido momentos de todo, en algunos momentos era una delicia por la documentación que tienen y por otros iba más perdida que un pingüino en el desierto y los atascos eran monumentales además de la presión del cliente que tenía que tener el proyecto en funcionamiento un mes y pico antes de que se me diese acceso al código para poder arreglar y aplicar las funcionalidades extra que se requerían. El proyecto era uno que había dejado a medias otro desarrollador y tuve que rehacer todo el código porqué tal como se me entregó la aplicación había cosas básicas de funcionamiento rotas, además de variables en inglés, en castellano y catalán (no es el primer proyecto que me encuentro así).

Django oscar se usa como aplicación de Backend y de frontend hay desplegado un NextJS que tras dar alguna que otra vuelta he terminado modificando alguna cosa.

En entorno local de desarrollo todo funcionaba correctamente, pero al ponerlo en producción la cosa se ha puesto divertida y ha requerido investigar varias cosas que voy a exponer en este post en modo de notas.

La aplicación de frontend se conecta con django oscar por API y hasta que no añadí la opción CSRF_TRUSTED_ORIGINS la comunicación era infructuosa.

# vi settings.py
# this allows nextjs to connect to django without using csrf_token
CSRF_TRUSTED_ORIGINS = 'http://127.0.0.1'
CSRF_COOKIE_SAMESITE = "None"
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "None"

Hasta aquí, la comunicación en local bien, el nextjs se conecta a django por http://127.0.0.1:8000.

Al montar el uwsgi para django (instalar entorno de producción de python), cambiando la url de comunicación al dominio expuesto a internet de django-oscar, adiós comunicación. Se ha probado de levantar una instancia de django con “python manage.py runserver” para que se levantase http://127.0.0.1:8000 la comunicación PUT y POST tampoco funcionaba (creo, y creo porqué no se ha podido llegar a probar por los errores de página con mixto http y https) y además las imágenes en el frontend se exponían con http://127.0.0.1:8000 y evidentemente no eran accesibles desde fuera del servidor.

Se ha tratado de poner el CSRF_TRUSTED_ORIGINS a varias configuraciones (IP pública, IP interna, dominio del frontend) y nada, incluso se ha puesto * y tampoco.

Otra prueba que se ha hecho y motivo por el cuál hago este post por parecerme una solución curiosa aunque poco recomendable para poner un django o aplicación de python en producción es levantar el runserver pero sobre https

Para ello será necesario instalar

# pip install django-extensions Werkzeug pyOpenSSL
# pip freeze > requirements.txt
# apt -y install python3-openssl # esto no sé si realmente es necesario si se instala el pyOpenSSL

Luego en settings.py se añade en INSTALLED_APPS el django-extensions

# vi settings.py
INSTALLED_APPS = [
     ....
     "django_extensions",
]

Luego se ejecuta el runserver así (como ya tenía certificados de letsencrypt le he puesto los certificados)

# python manage.py runserver_plus --cert-file /etc/letsencrypt/live/tgcback.xxx.com/cert.pem --key-file /etc/letsencrypt/live/tgcback.xxx.com/privkey.pem tgcback.xxx.com:8000

Pero no había nada accesible a la URL en el puerto 8000. Así que he vuelto al post donde nos plantean usar mkcert para generar certificados autofirmados

# apt -y install mkcert
# mkcert -cert-file cert.pem -key-file key.pem localhost 127.0.0.1

Y he ejecutado el runserver_plus así

python manage.py runserver_plus --cert-file /root/certs/cert.pem --key-file /root/certs/key.pem 0.0.0.0:8000

Era accesible pero evidentemente la comunicación era infructuosa por un problema de certificados.

He probado también con nginx machacar el https autofirmado así

   location / {
    proxy_pass https://127.0.0.1:8000; 
    proxy_ssl_server_name on;

No ha funcionado tampoco la comunicación, pero también lo dejo aquí como nota interesante a tener en cuenta cuando pueda ser necesario.

Y aquí lo dejo, de momento no hemos hallado la solución para que funcione el PUT y el POST en producción sin exponer ips locales que evidentemente no sirven. Mi propuesta es de modificar las URL en nextjs.

Hasta el momento contenta de haber descubierto cosillas nuevas, pero frustrada de aún no tener la aplicación funcionando en producción según lo esperado y un trabajo que se está alargando más de lo que me gustaría.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.