MP 07: Desarrollo web entorno servidor
Sesión de repaso
Diciembre 2023
Contenido
1. UF1: Programación web en entorno servidor
2. UF2: Generación dinámica de páginas web
3. UF3: Técnicas de acceso a datos
4. UF4: Servicios web. Páginas dinámicas interactivas. Webs híbridas
2
Arquitectura Cliente-Servidor
• Cliente: software que realiza solicitudes a un servidor para obtener un resultado
y, generalmente, mostrarlo a un usuario. Ej: navegador web, app Android/iOS
• Servidor: software que recibe peticiones, las procesa y devuelve una respuesta
3
Protocolo HTTP(s)
• Existen varios tipos de solicitudes HTTP, las más habituales son:
• GET: Obtener datos
• En la solicitud no se puede especificar un cuerpo, por lo que si se quiere enviar
algún dato al servidor debe hacerse como parámetro en la URL. Por ejemplo:
http://dominio.com?parametro=valor
• Se usa, por ejemplo, en la primera solicitud para cargar el HTML/CSS/JS de una
página web
• POST: Insertar/actualizar datos
• En el cuerpo de la solicitud normalmente se envían los datos a modificar. También
se pueden enviar datos como parámetro en la URL.
4
Protocolo HTTP(s)
5
Ejemplo GET
URL:
[…]/index.php?nombre=Francisco
Index.php:
<?php
$nombre = "";
if (isset($_GET["nombre"])){
$nombre = $_GET["nombre"];
}
echo $nombre;
?>
6
Ejemplo POST
Index.php:
<form method="post" action="publicar.php">
<input type="text" name="nombre" />
<input type="text" name="texto" />
<button>Aceptar</button>
</form>
Publicar.php:
<?php if (isset($_POST["nombre"]) && isset($_POST["texto"])){
echo $_POST["nombre"];
echo $_POST["texto"];
} ?>
7
Código cliente vs servidor
Código servidor:
• Es el más apropiado para operaciones complejas como leer/escribir a una base
de datos, ya que:
• El código fuente no es accesible para el usuario
• Se ejecuta únicamente en el servidor web
• Puede ser en casi cualquier lenguaje (PHP, Java, .NET, etc.)
Código cliente:
• Operaciones relacionadas con la interfaz de usuario (UI)
• Se ejecuta únicamente en el navegador web del usuario.
• Generalmente en JavaScript
8
Otras palabras clave de PHP
• Include, include_once, require, require_once
<?php include “cabecera.html” ?>
• PHP embebido en el HTML:
<input type="text" name="texto" value="<?php echo $texto; ?>"/>
• Bucles:
$array = array(1, 2, 3);
foreach ($array as $valor){
echo $valor . "<br/>";
}
• Clases:
<?php class Mensaje{
public $nombre;
public function imprimirNombre(){
echo $this->nombre;
}
}?>
9
Contenido
1. UF1: Programación web en entorno servidor
2. UF2: Generación dinámica de páginas web
3. UF3: Técnicas de acceso a datos
4. UF4: Servicios web. Páginas dinámicas interactivas. Webs híbridas
10
Diseño multicapa
• Para hacer que los desarrollos software sean fácilmente ampliables y
mantenibles, lo recomendado es segmentarlo en distintas unidades de código
con una sola responsabilidad, concepto similar al que fundamenta la POO.
• En el diseño de aplicaciones, esto se consigue separando el código en distintas
capas, cada una con su responsabilidad. Por ejemplo:
• Capa vista: dibujado de la interfaz y respuesta a acciones del usuario
• Capa modelo: lógica de negocio y acceso a datos.
11
Estado en HTTP(s)
• El protocolo HTTP(s) es un protocolo sin estado, lo cual significa que no permite
almacenar ningún tipo de información. Cualquier información que se desee
almacenar debe hacerse en el cliente o en el servidor.
• Cualquier aplicación hoy en día necesita almacenar un estado para las distintas
operaciones que los usuarios realizan
12
Almacenamiento de estado
• Almacenamiento en cliente:
• En el propio HTML (campos ocultos, campos visibles, etc.)
• En las cookies
• En el almacenamiento del navegador (localStorage, sessionStorage, etc.)
• Almacenamiento de datos en servidor:
• En memoria RAM (en el propio código o en la sesión)
• Almacenamiento externo (base de datos, disco duro, etc.)
13
Sesiones en servidor
• Las sesiones son un espacio de almacenamiento que usa el servidor web para
guardar distinta información
• Los datos almacenados en la sesión son independientes para cada usuario, ningún
usuario puede acceder a los datos de otro.
• Las sesiones se identifican para cada usuario en el servidor asignándole un id de
sesión, que es una clave única.
• El id de sesión se genera y se le envía al usuario en la primera respuesta HTTP y
se almacena en una cookie.
• El servidor usa la cookie para saber cómo vincular a un usuario con su sesión.
• En PHP se accede usando la supervariable global $_SESSION
14
HTML dinámico
verOferta.php:
<?php if (isset($oferta)): ?>
<div>Nombre: <?php echo $oferta->nombre; ?></div>
<div>Texto: <?php echo $oferta->texto; ?></div>?></div>
<?php endif; ?>
Index.php (asumiendo que el método obtenerOfertas() existe y devuelve las ofertas):
<?php
$ofertas = obtenerOfertas();
foreach($ofertas as $oferta){
include "verOferta.php";
}
?>
15
Autenticación
• Es el mecanismo mediante el cual un usuario se identifica en la aplicación y
puede realizar acciones en función de sus permisos.
• Es importante garantizar que ningún usuario tendrá acceso a aquellas páginas
para las que no tiene permisos.
• Si un usuario no está autenticado e intenta acceder a una página que requiere
autenticación, se le debe redirigir a la página de login.
16
Autenticación en PHP
Asumiendo que el método validar($usuario, $contrasena) existe y devuelve true si son
correctos y false en caso contrario:
<?php
class Autenticacion{
public static function estaAutenticado(){
return isset($_SESSION["usuario"]);
}
public static function autenticar($usuario, $contrasena){
if (validar($usuario, $contrasena)){
$_SESSION["usuario"] = $usuario;
return true;
}
return false;
}
}
?>
17
Contenido
1. UF1: Programación web en entorno servidor
2. UF2: Generación dinámica de páginas web
3. UF3: Técnicas de acceso a datos
4. UF4: Servicios web. Páginas dinámicas interactivas. Webs híbridas
18
Acceso a datos
• El acceso a datos suele representar el nivel más bajo en el diseño de una
aplicación
• Otras partes de la aplicación utilizarán la capa de acceso a datos, pero la capa
de acceso a datos no suele utilizar ninguna otra capa
• Sí puede utilizar librerías para acceder a la infraestructura donde se encuentre la
información
• El acceso a datos no se limita únicamente a bases de datos relacionales
(MySQL, SQL Server, Oracle, etc.). También puede ser:
• Bases de datos no relacionales (MongoDB, DynamoDB, etc.)
• Ficheros en un disco de almacenamiento
• Conexión a un servicio externo (almacenamientos Cloud, API REST, etc.)
• Existen patrones de diseño que nos permiten independizar el código del tipo de
datos que estemos utilizando, por ejemplo el DAO (Data Access Object) o el
Repositorio
19
Patrón DAO
20
Configuración de la conexión
• Los datos de conexión nunca pueden aparecer en el código fuente
• Si cambiamos de servidor, el código deja de funcionar
• Lo normal es tener un fichero de configuración o similar, que podamos modificar de forma
sencilla en caso de que se necesite algún cambio:
<?php
$config = parse_ini_file("config.ini");
$conexion = new mysqli($config["host"], $config["user"], $config["pass"],
$config["bd"]);
?>
Config.ini:
host=localhost
user=root2
pass=
bd=ofertas
21
Seguridad de los datos
• Ninguna contraseña ni dato sensible debe almacenarse en plano en la base de
datos.
• Para las contraseñas normalmente se almacena un hash (resumen) de la
contraseña, que permite comprobar si la contraseña es correcta pero es imposible
obtener la contraseña a partir del hash.
• Por ejemplo, usando el algoritmo SHA256:
• Texto: Prueba
• Hash: 655e786674d9d3e77bc05ed1de37b4b6bc89f788829f9f3c679e7687b410c89b
22
Evitar inyección de SQL
• La inyección de SQL consiste en utilizar un valor de alguno de los parámetros en
una consulta SQL para modificarla y ejecutar código arbitrario para el que la
consulta no está diseñado
<?php
$mysqli = new mysqli(...);
$consulta = "SELECT * FROM ofertas WHERE titulo = '$titulo' ";
$mysqli->query($consulta);
?>
• En PHP la mejor forma de evitar la inyección de SQL es parametrizar consultas:
• En la consulta se usan interrogantes para identificar los parámetros.
• Se utiliza el método bind_param para asignar los valores de forma segura.
23
Contenido
1. UF1: Programación web en entorno servidor
2. UF2: Generación dinámica de páginas web
3. UF3: Técnicas de acceso a datos
4. UF4: Servicios web. Páginas dinámicas interactivas. Webs
híbridas
24
Servicios web
• Un servicio web es una aplicación que recibe solicitudes, las procesa y devuelve
una respuesta.
• Utilizan el protocolo HTTP.
• Las API REST son uno de los tipos de servicios web más usados hoy en día.
• Se basa en los métodos estándar del protocolo HTTP:
• GET, POST, PUT, DELETE, etc.
• Permite enviar y recibir cualquier tipo de datos:
• JSON
• XML
• Subida/descarga de los bytes de un fichero
• …
• Tanto la solicitud como la respuesta pueden incluir la cabecera Content-Type para
especificar el tipo de información que se está enviando o recibiendo
25
Tipos de solicitud API REST
• Al basarse en HTTP, los tipos de solicitud coinciden con los métodos HTTP:
• POST
• GET
• PUT
• DELETE
• …
• Cómo acceder al cuerpo de las solicitudes en PHP:
<?php
$cuerpo = file_get_contents("php://input");
?>
• En los solicitudes de tipo GET no se puede recibir un cuerpo, solo se recibe
información a través de los parámetros de la URL
26
Diseño habitual de endpoints en una API REST
27
Probar APIs REST
• Se puede probar a través de la aplicación que haga uso de ella
• Es posible que todavía no la tengamos implementada (como en la actividad)
• Se puede probar también usando herramientas que nos permitan realizar
peticiones HTTP a la API REST
• Postman
• Swagger
• REST Client
• …
28
Autenticación mediante API Keys
• Se usa normalmente a nivel aplicación u organización, ya que la generación de
API Keys suele ser manual
• No válidas para aplicaciones JavaScript, ya que el API Key tiene que ser
completamente secreto.
29
Implementación en PHP de autenticación con API Keys
• Crear un fichero centralizado que pueda ser incluido en todos los endpoints
<?php include_once "autorizacion.php"; ?>
• En dicho fichero se debe verificar que la petición HTTP contiene una cabecera con
una API Key válida
• Si la contiene, no hacemos nada, la solicitud continúa con normalidad
• Si no la contiene, devolvemos error 401 Unauthorized y detenemos el procesamiento
con exit()
<?php $headers = getallheaders();
if (!isset($headers["ApiKey"]) || $headers["ApiKey"] != "..."){
http_response_code(401);
echo "Debes proporcionar un ApiKey";
exit();
} ?>
30