User Tools

Site Tools


proyecto:armar_la_aplicacion_inicial

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
proyecto:armar_la_aplicacion_inicial [2022/04/20 06:07] – [Servidor Web] ahoganproyecto:armar_la_aplicacion_inicial [2023/04/27 20:10] (current) sferrada
Line 1: Line 1:
 ====== Armar la Aplicación ====== ====== Armar la Aplicación ======
- 
-OJO: en cualquier parte del tutorial donde se mencione XX, este es el NÚMERO DE LA MÁQUINA, no su número de grupo. 
  
 ===== Objetivo ===== ===== Objetivo =====
Line 8: Line 6:
  
    * Como fue mencionado antes, hay que tener al menos tres consultas demostrando una mezcla de rasgos de SQL, es decir, joins, consultas anidadas, agregación, etc.     * Como fue mencionado antes, hay que tener al menos tres consultas demostrando una mezcla de rasgos de SQL, es decir, joins, consultas anidadas, agregación, etc. 
 +   * Al menos dos de las consultas deberían incluir uno o más parámetros ingresados por el usuario de la aplicación web.
    * No es necesario tener todos los rasgos en todas las consultas. La idea es que se demuestren los rasgos en alguna consulta. Se puede empezar con una consulta simple.    * No es necesario tener todos los rasgos en todas las consultas. La idea es que se demuestren los rasgos en alguna consulta. Se puede empezar con una consulta simple.
    * Es importante usar indices, vistas, etc., para optimizar las consultas.    * Es importante usar indices, vistas, etc., para optimizar las consultas.
Line 20: Line 19:
 Independientemente de la opción que se elija, la seguridad de la aplicación será parte de la evaluación del proyecto, así que hay que: Independientemente de la opción que se elija, la seguridad de la aplicación será parte de la evaluación del proyecto, así que hay que:
   * Usar sentencias precompiladas.   * Usar sentencias precompiladas.
-  * Crear un usuario para la aplicación que tenga solo el acceso mínimo requerido. +  * Crear un usuario para la aplicación que tenga solo el acceso mínimo requerido (si es que no se usa Django)
  
 Con respecto al último punto, la idea es no usar un superuser ''cc3201'' en la aplicación con acceso a todo, sino crear un usuario nuevo (p.ej. ''webuser'') con una contraseña (ojo: será más fácil si se evitan espacios y "caracteres especiales" y si se usan sólo caracteres alfanuméricos) y permitirle solo acceso de lectura a las tablas pertinentes con ''GRANT'', p.ej.: Con respecto al último punto, la idea es no usar un superuser ''cc3201'' en la aplicación con acceso a todo, sino crear un usuario nuevo (p.ej. ''webuser'') con una contraseña (ojo: será más fácil si se evitan espacios y "caracteres especiales" y si se usan sólo caracteres alfanuméricos) y permitirle solo acceso de lectura a las tablas pertinentes con ''GRANT'', p.ej.:
Line 26: Line 25:
 <code> <code>
 CREATE USER webuser WITH PASSWORD 'contrasena'; CREATE USER webuser WITH PASSWORD 'contrasena';
 +GRANT CONNECT ON DATABASE cc3201 TO webuser;
 GRANT USAGE ON SCHEMA proyecto TO webuser; GRANT USAGE ON SCHEMA proyecto TO webuser;
 ... ...
Line 32: Line 32:
  
 ... y después usar ''webuser'' y su contraseña en la aplicación. Hay más información sobre [[https://www.postgresql.org/docs/11/static/sql-grant.html|GRANT aquí]]. ... y después usar ''webuser'' y su contraseña en la aplicación. Hay más información sobre [[https://www.postgresql.org/docs/11/static/sql-grant.html|GRANT aquí]].
 +
 +Hay que tener cuidado con consultas como:
 +
 +<code>
 +SELECT * FROM tabla WHERE col = 'val';
 +</code>
 +
 +En particular, esta consulta no ha especificado el esquema, así que Postgres usará el ''SEARCH_PATH'' del usuario para identificar el primer esquema con la relación ''tabla''. Pero ''webuser'' puede tener un ''SEARCH_PATH'' diferente al ''SEARCH_PATH'' de ''cc3201''. Una solución sería definir bien el ''SEARCH_PATH'' de ''webuser'', pero ojo que si cambia el ''SEARCH_PATH'' en el futuro, la aplicación puede dejar de funcionar. Si una consulta va a ser usada durante mucho tiempo (por ejemplo, está codificada en una aplicación), la mejor solución es siempre especificar los esquemas de las tablas (o de las vistas, etc.) referenciadas:
 +
 +<code>
 +SELECT * FROM esquema.tabla WHERE col = 'val';
 +</code>
 +
 +Así funcionará ante cambios al ''SEARCH_PATH'' del usuario de la aplicación.
 ===== Servidor Web ===== ===== Servidor Web =====
  
Line 62: Line 76:
 ... aceptando cada vez que pida confirmación. Esto es necesario hacerlo solo una vez. [[https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=245022|Fuente]] ... aceptando cada vez que pida confirmación. Esto es necesario hacerlo solo una vez. [[https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=245022|Fuente]]
  
-**Nota 2**: Durante el tutorial se pedirá instalar cierta versión de algún paquete, ejemplo: +**Nota 2**: Si al intentar actualizar o ejecutar algo sale este error:
-<code> +
-sudo apt-get install tomcat7 +
-</code> +
-Pero si dicho paquete no se encuentra,  +
-<code> +
-E: Unable to locate package tomcat7 +
-</code> +
- +
-... probar buscando si el paquete se encuentra en otra versión: +
- +
-<code> +
-apt-cache search tomcat +
-</code> +
-<code> +
-... +
-tomcat9 - Apache Tomcat 9 - Servlet and JSP engine +
-tomcat9-admin - Apache Tomcat 9 - Servlet and JSP engine -- admin web applications +
-tomcat9-common - Apache Tomcat 9 - Servlet and JSP engine -- common files +
-tomcat9-docs - Apache Tomcat 9 - Servlet and JSP engine -- documentation +
-tomcat9-examples - Apache Tomcat 9 - Servlet and JSP engine -- example web applications +
-tomcat9-user - Apache Tomcat 9 - Servlet and JSP engine -- tools to create user instances +
-... +
-</code> +
- +
-... en este caso encontramos la versión 9. +
- +
-**Nota 3**: Si al intentar actualizar o ejecutar algo sale este error:+
 <code> <code>
 E: You don't have enough free space in /var/cache/apt/archives/. E: You don't have enough free space in /var/cache/apt/archives/.
Line 108: Line 95:
  
   * PRO: más fácil de instalar y se puede empezar rápidamente con algunos ejemplos.   * PRO: más fácil de instalar y se puede empezar rápidamente con algunos ejemplos.
-  * CON: hay que programar en PHP. +  * CON: hay que programar (un poco) en PHP.
-  * PRO: en realidad no hay que programar en PHP.+
  
-Apache2 es un servidor web. PHP es un scripting language. Armaremos Apache2 y crearemos la aplicación después con PHP.+Apache2 es un servidor web. PHP es un scripting language que podemos mezclar con HTML. Armaremos Apache2 y crearemos la aplicación después con PHP.
  
 === Instalar apache2 === === Instalar apache2 ===
Line 136: Line 122:
 Para instalar PHP con soporte para apache2 y postgres: Para instalar PHP con soporte para apache2 y postgres:
  
-<code>sudo apt-get install php7.libapache2-mod-php7.php7.3-pgsql</code>+<code>sudo apt-get install php7.libapache2-mod-php7.php7.4-pgsql</code>
  
 Ahora, tenemos que reiniciar Apache: Ahora, tenemos que reiniciar Apache:
Line 157: Line 143:
 ?> ?>
 </code> </code>
 +
 +... y guardar.
  
 Ir aquí para verificar que funcione: Ir aquí para verificar que funcione:
Line 235: Line 223:
 Si funciona, podrán adaptar el ejemplo para crear su aplicación. Hay [[http://phpdelusions.net/pdo|un tutorial aquí]] que puede ser útil. Si funciona, podrán adaptar el ejemplo para crear su aplicación. Hay [[http://phpdelusions.net/pdo|un tutorial aquí]] que puede ser útil.
  
-OJO: ¡Es importante usar métodos seguros contra inyección! Mi ejemplo es solo una prueba, no un ejemplo a seguir.+OJO: ¡Es importante usar métodos seguros contra inyección! El ejemplo acá es solo una prueba, no un ejemplo a seguir. HINT: Hay un ejemplo seguro indicado en el lab 5.
  
 === Debugear / Logs === === Debugear / Logs ===
Line 245: Line 233:
 Al final del archivo habrá los errores más recientes. Puedes usar la barra espaciadora para avanzar en el archivo. El error debería proveer más información para resolver el problema. Al final del archivo habrá los errores más recientes. Puedes usar la barra espaciadora para avanzar en el archivo. El error debería proveer más información para resolver el problema.
  
-Si el error no es de Apache2 + PHP, puede tratarse de postgres. Para ver los logs hay que abrir:+Si el error no es de Apache2 + PHP, puede tratarse de Postgres. Para ver los logs hay que abrir:
  
 <code>sudo more /var/log/postgresql/postgresql-11-main.log</code> <code>sudo more /var/log/postgresql/postgresql-11-main.log</code>
Line 257: Line 245:
   * PRO: da una abstracción de todo en Python   * PRO: da una abstracción de todo en Python
   * CON: hay que programar en Python   * CON: hay que programar en Python
-  * CON: muy **muy** difícil de configurar inicialmente+  * CON: difícil de configurar inicialmente
   * CON: mucho más "pesado" e "indirecto" que PHP en particular   * CON: mucho más "pesado" e "indirecto" que PHP en particular
  
 La idea de Django es proveer una abstracción Modelo/Vista/Controlador de una aplicación Web en Python, donde el modelo captura los datos (p.ej. SQL) y la lógica (p.ej. python), la vista representa la información de salida que hay que desplegar para el usuario (p.ej. HTML), y el controlador acepta la entrada del usuario y la convierte en modificaciones al modelo (p.ej. para actualizar la base de datos desde una petición en HTML). La idea de Django es proveer una abstracción Modelo/Vista/Controlador de una aplicación Web en Python, donde el modelo captura los datos (p.ej. SQL) y la lógica (p.ej. python), la vista representa la información de salida que hay que desplegar para el usuario (p.ej. HTML), y el controlador acepta la entrada del usuario y la convierte en modificaciones al modelo (p.ej. para actualizar la base de datos desde una petición en HTML).
  
-A mi parecer, Django tiene un costo inicial muy alto, pero después uno tendrá una abstracción más limpia, la cual es útil, en particular, para aplicaciones complejas. Si ustedes quieren hacer algo más simple y rápido, PHP sería la mejora opción. Si ustedes quieren aprender algo de un framework usado bastante en la práctica, Django es una buena opción PERO aquí sólo se dará la información suficiente para instalar y configurar una aplicación básica. No será un tutorial completo (el enfoque del curso es bases de datos, no aplicaciones web). +Django tiene un costo inicial muy alto, pero después uno tendrá una abstracción más limpia, la cual es útil, en particular, para aplicaciones complejas. Si ustedes quieren hacer algo más simple y rápido, PHP sería la mejora opción. Si ustedes quieren aprender algo de un framework usado bastante en la práctica, Django es una buena opción PERO aquí sólo se dará la información suficiente para instalar y configurar una aplicación básica. No será un tutorial completo (el enfoque del curso es bases de datos, no aplicaciones web). Aquí puede encontrar más información útil: desde tutoriales hasta documentación: [[https://www.djangoproject.com/start/|Django docs]].
- +
-Aqui puede encontrar más información úti: desde tutoriales hasta documentación: [[https://www.djangoproject.com/start/|Django docs]].+
  
 === Instalar Python === === Instalar Python ===
Line 287: Line 273:
 === Instalar Django === === Instalar Django ===
  
-Usaremos PIP (un instalador para packages de Python) para instalar la versión más reciénte de Django para python3.+Usaremos PIP (un instalador para packages de Python) para instalar la versión más reciente de Django para python3.
  
 <code> <code>
Line 1161: Line 1147:
  
 Con el ejemplo previo, y por fin, tienen todos los ingredientes para armar su aplicación usando Django. Un recordatorio: hay que verificar que la aplicación **esté segura contra inyección**. Puede ser que los ejemplos que doy aquí no sean seguros, entonces hay que investigar en la Web si son seguros o no. Con el ejemplo previo, y por fin, tienen todos los ingredientes para armar su aplicación usando Django. Un recordatorio: hay que verificar que la aplicación **esté segura contra inyección**. Puede ser que los ejemplos que doy aquí no sean seguros, entonces hay que investigar en la Web si son seguros o no.
 +
 +==== Opción 3: Java Servlets ====
 +
 +  * PRO: se puede programar en Java
 +  * CON: difícil de instalar y configurar
 +  * CON: una metodología desactualizada (pero con muchos sistemas legados todavía)
 +  * CON: hay que programar en Java
 +  
 +La opción de Java Servlets es una opción legada que tenía relevancia cuando el lenguaje usado en el curso Introducción a Programación fue Java. En vez de borrar la opción, la hemos mantenido acá, pero en general, no es una opción recomendada, salvo en el caso de que un grupo realmente quiera programar en Java.
 +
 +=== Instalar tomcat9 ===
 +
 +Hay que instalar ''tomcat9'', un servidor web para Java Servlets:
 +
 +<code>
 +sudo apt-get update
 +sudo apt-get install tomcat9 tomcat9-admin tomcat9-examples tomcat9-docs authbind
 +</code>
 +
 +=== Configurar tomcat9 ===
 +
 +Tenemos que poner un usuario "admin" y una contraseña:
 +
 +<code>
 +sudo nano /etc/tomcat9/tomcat-users.xml
 +</code>
 +
 +Aquí:
 +
 +<code>
 +<tomcat-users>
 +</tomcat-users>
 +</code>
 +
 +Hay que poner (ojo: la página es publica así que ¡es importante elegir una contraseña segura! es decir, ¡no ''password'' ni ''holaprueba''!):
 +
 +<code>
 +<tomcat-users>
 +    <user username="admin" password="holaprueba" roles="manager-gui,admin-gui"/>
 +</tomcat-users>
 +</code>
 +
 +... y guardar el archivo.
 +
 +Por defecto, tomcat9 será instalado con el puerto 8080, el cual no es accesible desde afuera. Tenemos que cambiarlo a 80 (el puerto por defecto en HTTP).
 +
 +<code>
 +sudo nano /etc/tomcat9/server.xml
 +</code>
 +
 +Hay que cambiar (ojo que no es ''8005'')
 +
 +<code>
 +<Connector port="8080" protocol="HTTP/1.1"
 +</code>
 +
 +... por ...
 +
 +<code>
 +<Connector port="80" protocol="HTTP/1.1"
 +</code>
 +
 +... y guardar el archivo.
 +
 +Ahora ...
 +
 +<code>
 +sudo nano /etc/default/tomcat9
 +</code>
 +
 +Hay que cambiar:
 +
 +<code>
 +#AUTHBIND=no
 +</code>
 +
 +por (ojo: hay que borrar el gato):
 +
 +<code>
 +AUTHBIND=yes
 +</code>
 +
 +... y guardar el archivo.
 +
 +El próximo paso es deshabilitar IPv6 porque ''AUTHBIND'' solo funciona con IPv4.
 +
 +<code>
 +sudo nano /usr/share/tomcat9/bin/setenv.sh
 +</code>
 +
 +Hay que poner:
 +
 +<code>
 +export CATALINA_OPTS="$CATALINA_OPTS -Djava.net.preferIPv4Stack=true"
 +</code>
 +
 +Después, en:
 +
 +<code>
 +sudo nano /usr/share/tomcat9/bin/startup.sh
 +</code>
 +
 +Hay que comentar la primera línea aquí y agregar la segunda:
 +
 +<code>
 +# exec "$PRGDIR"/"$EXECUTABLE" start "$@" 
 +exec authbind --deep "$PRGDIR"/"$EXECUTABLE" start "$@"
 +</code>
 +
 +Por fin, está lista la configuración del puerto 80.
 +
 +Finalmente, hay que darle a Tomcat acceso al controlador de Postgres:
 +
 +<code>
 +sudo apt-get install wget
 +cd /usr/share/tomcat9/lib/
 +sudo wget https://jdbc.postgresql.org/download/postgresql-9.4.1212.jre6.jar
 +</code>
 +
 +Ahora se puede usar JDBC para consultar a Postgres desde Tomcat.
 +
 +=== Correr el servidor de tomcat9 ===
 +
 +En el caso de que Apache esté instalado y corriendo, hay que deshabilitarlo (si no está instalado, se puede saltar este paso):
 +
 +<code>
 +sudo /etc/init.d/apache2 stop
 +</code>
 +
 +Está lista la configuración así que tenemos que reiniciar tomcat9:
 +
 +<code>
 +sudo service tomcat9 restart
 +</code>
 +
 +Ahora, se puede ir aquí para verificar que funcione (ojo: ''XX'' es el número del grupo):
 +
 +<code>
 +http://cc3201.dcc.uchile.cl/grupoXX/
 +</code>
 +
 +Hemos instalado Tomcat con el cual podemos instalar Java Servlets. :) 
 +
 +=== Un ejemplo de un Java Servlet ===
 +
 +(//Una confesión: en el ejemplo que doy, pongo HTML en el código de Java. Eso es muy feo porque mezcla la presentación y la lógica de la aplicación. Sería muchísimo mejor usar JSP con los servlets, pero también más complicado.//)
 +
 +Efectivamente, un servlet es como un paquete de código en Java en un formato "WAR". Es como un JAR pero con algunas diferencias: tiene una página web y algunas configuraciones más.
 +
 +Descargar [[http://aidanhogan.com/teaching/tools/cc3201/servlet-test.zip|servlet-test.zip]] y abrirlo en Eclipse o IntelliJ, etc.
 +
 +En ''src/'' está el código.
 +
 +En ''web/resources/'' se pueden poner archivos estáticos como imágenes, etc.
 +
 +En ''web/resources/index.html'' está la página por defecto.
 +
 +En ''web/WEB-INF/web.xml'' está la configuración del servlet.
 +
 +En ''web/WEB-INF/context.xml'' hay que cambiar el ''username'' y el ''password''. Se debería usar el usuario de la aplicación (p.ej. ''webuser''), no un super-usuario como ''cc3201'' o ''postgres''. No hay que cambiar el IP ni el puerto (la aplicación será instalada directamente en la máquina virtual así que la conexión será por localhost) ni la base de datos.
 +
 +Tenemos que crear un paquete ''.war''. Sobre ''build.xml'' hacer clic derecho, ''Run As > Ant Build''.
 +
 +Ahora hay que refrescar el proyecto: hacer clic en la carpeta del proyecto y presionar ''F5''. En ''dist/'', debería haber un archivo ''bddservlet.war''.
 +
 +Tenemos que subir el archivo ''bddservlet.war'' a la carpeta ''/var/lib/tomcat9/webapps/'' pero será más fácil si ''cc3201'' tiene permisos para estas carpetas:
 +
 +<code>
 +sudo chown -R tomcat9:tomcat9 /var/lib/tomcat9
 +sudo chmod -R g+r /var/lib/tomcat9/conf
 +sudo chmod -R g+w /var/lib/tomcat9/conf
 +sudo chmod -R g+w /var/lib/tomcat9/logs
 +sudo chmod -R g+w /var/lib/tomcat9/webapps
 +sudo chmod -R g+w /var/lib/tomcat9/work
 +sudo chmod -R g+s /var/lib/tomcat9/conf
 +sudo chmod -R g+s /var/lib/tomcat9/logs
 +sudo chmod -R g+s /var/lib/tomcat9/webapps
 +sudo chmod -R g+s /var/lib/tomcat9/work
 +sudo usermod -a -G tomcat9 cc3201
 +</code>
 +
 +Después, [[https://wiki.dcc.uchile.cl/cc3201/doku.php?id=proyecto:acceso_al_servidor#transferencia_de_datos|hay que usar]] ''scp'' o ''sftp'' o ''wget'' para poner ''bddservlet.war'' en la carpeta ''/var/lib/tomcat9/webapps/'' del servidor. Se instalará la aplicación automáticamente en la carpeta ''bddservlet/'' en ''/var/lib/tomcat9/webapps/bddservlet''. (Si uno hace la transferencia de nuevo, actualizará la carpeta también.)
 +
 +Ir a:
 +
 +<code>
 +http://grupoXX.cc3201.dcc.uchile.cl/bddservlet/
 +</code>
 +
 +Aquí se pueden ver tres ejemplos simples de aplicaciones que pueden adaptar para su aplicación.
 +
 +OJO: ¡es importante usar métodos seguros contra inyección! Mi ejemplo es solo una prueba, no un ejemplo a seguir.
 +
 +Si hay un problema con el servlet, el log está aquí:
 +
 +<code>
 +sudo more /var/lib/tomcat9/logs/catalina.out
 +</code>
 +
 +... el error más común es un problema con la contraseña/usuario en ''web/WEB-INF/context.xml''. Por eso, hay que revisar los detalles en ''psql'' para verificar que estén correctos.
  
 ==== Opción 4: Algo diferente ==== ==== Opción 4: Algo diferente ====
  
-Se puede usar otra opción para armar la aplicación:+Tienen sudo, así que pueden usar otra opción para armar la aplicación:
  
-  * JSPSpringStruts, Flask, Rails, Zend, etc.+  * FlaskReactAngular, Rails, Spring, etc.
  
 ... pero no podremos ofrecerles soporte si hay problemas. ... pero no podremos ofrecerles soporte si hay problemas.
 +
 +====== Conexión Externa =====
 +
 +Finalmente, se deben configurar los puertos de modo que la aplicación web quede disponible para acceder a través de una URL. Puede encontrar instrucciones de como hacerlo visitando [[proyecto:conexion_externa|este enlace]].
proyecto/armar_la_aplicacion_inicial.1650434865.txt.gz · Last modified: 2022/04/20 06:07 by ahogan