{"id":230570,"date":"2022-12-09T10:45:00","date_gmt":"2022-12-09T07:45:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230570"},"modified":"2022-12-07T11:58:46","modified_gmt":"2022-12-07T08:58:46","slug":"envio-seguro-de-formularios-de-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/envio-seguro-de-formularios-de-wordpress\/","title":{"rendered":"Env\u00edo seguro de formularios de WordPress"},"content":{"rendered":"\n<p>Hace a\u00f1os escrib\u00ed una publicaci\u00f3n en la que compart\u00eda una funci\u00f3n p\u00fablica para determinar si el usuario ten\u00eda permisos para guardar informaci\u00f3n en la base de datos de WordPress. Puedes ver la esencia original en todo su esplendor antiguo (junto con los comentarios s\u00f3lidos) <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/4468321\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">aqu\u00ed<\/a><\/strong> (tiene cinco a\u00f1os, incluso, guau).<\/p>\n<p>Al igual que con cualquier cosa relacionada con la programaci\u00f3n, el tiempo pasa, las cosas se refinan y las cosas [con suerte] mejoran de lo que eran antes.<\/p>\n<p>Aunque todav\u00eda uso y recomiendo una variante de la <strong>funci\u00f3n user_can_save<\/strong> (o <strong>userCanSave<\/strong> ), tambi\u00e9n creo que es importante pasar por el proceso de separar el proceso de verificaci\u00f3n de la solicitud.<\/p>\n<p>As\u00ed que ahora no se trata solo de determinar si el usuario tiene permisos, sino de verificar la informaci\u00f3n de seguridad que proviene del cliente, ya sea a trav\u00e9s de una publicaci\u00f3n en el servidor o una solicitud realizada a trav\u00e9s de Ajax, y hacerlo usando buenas t\u00e9cnicas de programaci\u00f3n que se alinean tanto con WordPress como con PHP.<\/p>\n<p>Para ser claros, se trata m\u00e1s del env\u00edo seguro de formularios de WordPress desde una p\u00e1gina de opciones o una p\u00e1gina de configuraci\u00f3n que, digamos, un formulario proveniente de una plantilla. Ese es otro post para otro momento.<\/p>\n<p>Pero aun as\u00ed, somos muchos los que trabajamos en la creaci\u00f3n de aplicaciones en WordPress y eso requiere lo siguiente.<\/p>\n<h2>Env\u00edo seguro de formularios de WordPress<\/h2>\n<p>En esta publicaci\u00f3n, no me voy a preocupar por los detalles para determinar si algo es un <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_autosave\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">autoguardado<\/a><\/strong> o una <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_revision\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">revisi\u00f3n de la publicaci\u00f3n.<\/a><\/strong><\/p>\n<\/p>\n<p>Sin embargo, voy a explicar el proceso de tomar una funci\u00f3n que es responsable de validar la informaci\u00f3n entrante y hacerlo usando un enfoque moderno usando pr\u00e1cticas orientadas a objetos y tanto las API de WordPress como las funciones de PHP.<\/p>\n<h3>1 Comenzando en un nivel gen\u00e9rico<\/h3>\n<p>Desde el nivel b\u00e1sico, supongamos que hay una clase base de la cual hay otras subclases que aprovechan esta funci\u00f3n. Esto nos dice que necesitamos usar el modificador de visibilidad protegida.<\/p>\n<p>Tambi\u00e9n sabemos que vamos a tratar con un valor nonce de WordPress y una acci\u00f3n relacionada. Esto significa que la <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-function-signature-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">firma de la funci\u00f3n se ver\u00e1 as\u00ed<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action);<\/code><\/pre>\n<h3>2 Desinfecte los datos, verifique el Nonce<\/h3>\n<p>Seg\u00fan cualquier cosa que se publique en el servidor, sabemos que necesitaremos verificar que los datos est\u00e9n configurados y, de ser as\u00ed, necesitaremos desinfectar la informaci\u00f3n.<\/p>\n<p>Esto significa que vamos a necesitar las siguientes funciones:<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.isset.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Est\u00e1 establecido<\/a><\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strip-tags.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tira_etiquetas<\/a><\/li>\n<li><strong><a href=\"https:\/\/php.net\/manual\/en\/function.stripslashes.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tiras<\/a><\/strong><\/li>\n<\/ul>\n<p>Y tambi\u00e9n sabemos que necesitaremos verificar el nonce, por lo que tambi\u00e9n necesitaremos <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_verify_nonce\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_verify_nonce<\/a><\/strong>.<\/p>\n<h3>3 Un primer pase de trabajo<\/h3>\n<p>Un primer paso funcional de esta funci\u00f3n puede verse <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-verify-request-1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    return isset($_GET[$nonce]) &amp;&amp;\n           wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action);\n}\n<\/code><\/pre>\n<p>Pero, \u00bfqu\u00e9 sucede si alguien comparte datos que se env\u00edan mediante una solicitud <strong>POST<\/strong> (en lugar de una solicitud <strong>GET<\/strong> )? Entonces podr\u00edamos modificar la funci\u00f3n para que se vea <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-02-verify-request-2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    return (isset($_GET[$nonce]) &amp;&amp;\n            wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action)) || (isset($_POST[$nonce]) &amp;&amp;\n            wp_verify_nonce(strip_tags(stripslashes($_POST[$nonce])), $action)\n        );\n}\n<\/code><\/pre>\n<p>Y esto ser\u00eda suficiente. Pero si realmente queremos que una funci\u00f3n dada sea lo m\u00e1s pura posible, entonces podr\u00edamos dividirla a\u00fan m\u00e1s.<\/p>\n<h3>4 Una funci\u00f3n para cada prop\u00f3sito<\/h3>\n<p>Dado el c\u00f3digo anterior, sabemos que necesitamos manejar tanto las solicitudes GET como las solicitudes POST. PHP ofrece una funci\u00f3n <strong>filter_input<\/strong> que es \u00fatil, m\u00e1s f\u00e1cil de leer (bueno, esto es subjetivo), pero tambi\u00e9n pasa varias inspecciones de calidad del c\u00f3digo.<\/p>\n<p>Adem\u00e1s, podemos usar una funci\u00f3n <strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Factory_method_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">simple de f\u00e1brica<\/a><\/strong> para separar la l\u00f3gica en funciones separadas como esta:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162230-61e73927a6ca8.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162230-61e73927a6ca8.png\" alt=\"Env\u00edo seguro de formularios de WordPress\" ><\/a><\/p>\n<p>Primero, necesitamos escribir dos funciones separadas, una <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-03-verify-post-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para una solicitud POST:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprivate function verifyPostRequest($nonce, $action)\n{\n    return\n        isset($_POST[$nonce]) &amp;&amp;\n        wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_POST, $nonce))), $action);\n}<\/code><\/pre>\n<p>Y uno <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-04-verify-get-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para una solicitud GET:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprivate function verifyGetRequest($nonce, $action)\n{\n    return\n        isset($_GET[$nonce]) &amp;&amp;\n        wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_GET, $nonce))), $action);\n}<\/code><\/pre>\n<p>Entonces podemos unirlo en <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-05-verify-request-factory-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la funci\u00f3n original de esta manera:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    switch (strtolower($_SERVER['REQUEST_METHOD'])) {\n        case 'post':\n            return $this-&gt;verifyPostRequest($nonce, $action);\n            break;\n        case 'get':\n            return $this-&gt;verifyGetRequest($nonce, $action);\n            break;\n        default:\n            return false;\n            break;\n    }\n}<\/code><\/pre>\n<h2>Gesti\u00f3n limpia de solicitudes entrantes<\/h2>\n<p>Tal vez esto parezca una forma complicada de manejar una soluci\u00f3n simple dado el conjunto inicial de c\u00f3digo que se comparti\u00f3.<\/p>\n<p>Eso es ciertamente posible, especialmente si tiene limitaciones de tiempo o no le importa tanto dividir las cosas en los componentes at\u00f3micos (o incluso comprobables) m\u00e1s peque\u00f1os posibles.<\/p>\n<p>Pero si est\u00e1 buscando escribir c\u00f3digo orientado a objetos con el m\u00e1s alto grado de precisi\u00f3n, tal vez este proceso lo ayude exactamente con eso.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Se trata m\u00e1s del env\u00edo seguro de formularios de WordPress desde una p\u00e1gina de opciones o una p\u00e1gina de configuraci\u00f3n que de un formulario proveniente de una plantilla.<\/p>\n","protected":false},"author":1,"featured_media":236238,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[892,800,840,861],"tags":[1172],"class_list":["post-230570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-php-2","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230570"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236238"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}