Envío seguro de formularios de WordPress
Hace años escribí una publicación en la que compartía una función pública para determinar si el usuario tenía permisos para guardar información en la base de datos de WordPress. Puedes ver la esencia original en todo su esplendor antiguo (junto con los comentarios sólidos) aquí (tiene cinco años, incluso, guau).
Al igual que con cualquier cosa relacionada con la programación, el tiempo pasa, las cosas se refinan y las cosas [con suerte] mejoran de lo que eran antes.
Aunque todavía uso y recomiendo una variante de la función user_can_save (o userCanSave ), también creo que es importante pasar por el proceso de separar el proceso de verificación de la solicitud.
Así que ahora no se trata solo de determinar si el usuario tiene permisos, sino de verificar la información de seguridad que proviene del cliente, ya sea a través de una publicación en el servidor o una solicitud realizada a través de Ajax, y hacerlo usando buenas técnicas de programación que se alinean tanto con WordPress como con PHP.
Para ser claros, se trata más del envío seguro de formularios de WordPress desde una página de opciones o una página de configuración que, digamos, un formulario proveniente de una plantilla. Ese es otro post para otro momento.
Pero aun así, somos muchos los que trabajamos en la creación de aplicaciones en WordPress y eso requiere lo siguiente.
Envío seguro de formularios de WordPress
En esta publicación, no me voy a preocupar por los detalles para determinar si algo es un autoguardado o una revisión de la publicación.
Sin embargo, voy a explicar el proceso de tomar una función que es responsable de validar la información entrante y hacerlo usando un enfoque moderno usando prácticas orientadas a objetos y tanto las API de WordPress como las funciones de PHP.
1 Comenzando en un nivel genérico
Desde el nivel básico, supongamos que hay una clase base de la cual hay otras subclases que aprovechan esta función. Esto nos dice que necesitamos usar el modificador de visibilidad protegida.
También sabemos que vamos a tratar con un valor nonce de WordPress y una acción relacionada. Esto significa que la firma de la función se verá así :
<?php
protected function verifyRequest($nonce, $action);
2 Desinfecte los datos, verifique el Nonce
Según cualquier cosa que se publique en el servidor, sabemos que necesitaremos verificar que los datos estén configurados y, de ser así, necesitaremos desinfectar la información.
Esto significa que vamos a necesitar las siguientes funciones:
Y también sabemos que necesitaremos verificar el nonce, por lo que también necesitaremos wp_verify_nonce.
3 Un primer pase de trabajo
Un primer paso funcional de esta función puede verse así:
<?php
protected function verifyRequest($nonce, $action)
{
return isset($_GET[$nonce]) &&
wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action);
}
Pero, ¿qué sucede si alguien comparte datos que se envían mediante una solicitud POST (en lugar de una solicitud GET )? Entonces podríamos modificar la función para que se vea así:
<?php
protected function verifyRequest($nonce, $action)
{
return (isset($_GET[$nonce]) &&
wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action)) || (isset($_POST[$nonce]) &&
wp_verify_nonce(strip_tags(stripslashes($_POST[$nonce])), $action)
);
}
Y esto sería suficiente. Pero si realmente queremos que una función dada sea lo más pura posible, entonces podríamos dividirla aún más.
4 Una función para cada propósito
Dado el código anterior, sabemos que necesitamos manejar tanto las solicitudes GET como las solicitudes POST. PHP ofrece una función filter_input que es útil, más fácil de leer (bueno, esto es subjetivo), pero también pasa varias inspecciones de calidad del código.
Además, podemos usar una función simple de fábrica para separar la lógica en funciones separadas como esta:
Primero, necesitamos escribir dos funciones separadas, una para una solicitud POST:
<?php
private function verifyPostRequest($nonce, $action)
{
return
isset($_POST[$nonce]) &&
wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_POST, $nonce))), $action);
}
Y uno para una solicitud GET:
<?php
private function verifyGetRequest($nonce, $action)
{
return
isset($_GET[$nonce]) &&
wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_GET, $nonce))), $action);
}
Entonces podemos unirlo en la función original de esta manera:
<?php
protected function verifyRequest($nonce, $action)
{
switch (strtolower($_SERVER['REQUEST_METHOD'])) {
case 'post':
return $this->verifyPostRequest($nonce, $action);
break;
case 'get':
return $this->verifyGetRequest($nonce, $action);
break;
default:
return false;
break;
}
}
Gestión limpia de solicitudes entrantes
Tal vez esto parezca una forma complicada de manejar una solución simple dado el conjunto inicial de código que se compartió.
Eso es ciertamente posible, especialmente si tiene limitaciones de tiempo o no le importa tanto dividir las cosas en los componentes atómicos (o incluso comprobables) más pequeños posibles.
Pero si está buscando escribir código orientado a objetos con el más alto grado de precisión, tal vez este proceso lo ayude exactamente con eso.
