{"id":230970,"date":"2022-12-09T10:45:00","date_gmt":"2022-12-09T07:45:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230970"},"modified":"2022-12-07T11:58:48","modified_gmt":"2022-12-07T08:58:48","slug":"suojattu-wordpress-lomakkeen-laehetys","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/suojattu-wordpress-lomakkeen-laehetys\/","title":{"rendered":"Suojattu WordPress-lomakkeen l\u00e4hetys"},"content":{"rendered":"\n<p>Vuosia sitten kirjoitin viestin, jossa jaoin julkisen toiminnon selvitt\u00e4\u00e4kseni, oliko k\u00e4ytt\u00e4j\u00e4ll\u00e4 lupa tallentaa tietoja WordPress-tietokantaan. Voit n\u00e4hd\u00e4 alkuper\u00e4isen olemuksen kaikessa ik\u00e4\u00e4ntyneess\u00e4 loistossaan (yhdess\u00e4 kiinteiden kommenttien kanssa) <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/4468321\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4\u00e4ll\u00e4<\/a><\/strong> (se on jopa viisi vuotta vanha &#8211; vau).<\/p>\n<p>Kuten kaikissa ohjelmointiin liittyviss\u00e4 asioissa, aika kuluu, asiat jalostuvat ja asiat [toivottavasti] paranevat kuin ennen.<\/p>\n<p>Vaikka k\u00e4yt\u00e4n edelleen ja suosittelen <strong>user_can_save<\/strong> (tai <strong>userCanSave<\/strong>) -funktion muunnelmaa, mielest\u00e4ni on my\u00f6s t\u00e4rke\u00e4\u00e4 k\u00e4yd\u00e4 l\u00e4pi pyynn\u00f6n vahvistusprosessin erottaminen.<\/p>\n<p>Nyt ei siis ole kyse vain sen m\u00e4\u00e4ritt\u00e4misest\u00e4, onko k\u00e4ytt\u00e4j\u00e4ll\u00e4 k\u00e4ytt\u00f6oikeuksia, vaan asiakkaalta tulevien tietoturvatietojen tarkistaminen \u2013 olipa kyse sitten l\u00e4hett\u00e4misest\u00e4 takaisin palvelimelle tai Ajaxin kautta tehtyyn pyynt\u00f6\u00f6n \u2013 ja tehd\u00e4 se k\u00e4ytt\u00e4m\u00e4ll\u00e4 hyvi\u00e4 ohjelmointitekniikoita, jotka yhdenmukaistavat sek\u00e4 WordPressill\u00e4 ett\u00e4 PHP:ll\u00e4.<\/p>\n<p>Selvyyden vuoksi t\u00e4m\u00e4 koskee enemm\u00e4n suojattua WordPress-lomakkeen l\u00e4hett\u00e4mist\u00e4 asetussivulta tai asetussivulta kuin se on esimerkiksi mallista tuleva lomake. Se on toinen postaus toista kertaa.<\/p>\n<p>Silti monet meist\u00e4 ty\u00f6skentelev\u00e4t WordPressin sovellusten rakentamisen parissa ja jotka edellytt\u00e4v\u00e4t seuraavaa.<\/p>\n<h2>Suojattu WordPress-lomakkeen l\u00e4hetys<\/h2>\n<p>T\u00e4ss\u00e4 viestiss\u00e4 en aio k\u00e4sitell\u00e4 yksityiskohtia sen m\u00e4\u00e4ritt\u00e4miseksi, onko jokin <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_autosave\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">automaattinen tallennus<\/a><\/strong> vai j\u00e4lkiversio <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_revision\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">.<\/a><\/strong><\/p>\n<\/p>\n<p>Aion kuitenkin k\u00e4yd\u00e4 l\u00e4pi prosessin, jossa otan funktion, joka on vastuussa saapuvien tietojen validoinnista, ja teen sen k\u00e4ytt\u00e4m\u00e4ll\u00e4 modernia l\u00e4hestymistapaa k\u00e4ytt\u00e4en oliopohjaisia \u200b\u200bk\u00e4yt\u00e4nt\u00f6j\u00e4 ja sek\u00e4 WordPressin API- ett\u00e4 PHP-toimintoja.<\/p>\n<h3>1 Yleiselt\u00e4 tasolta alkaen<\/h3>\n<p>Oletetaan perustasolta, ett\u00e4 on olemassa perusluokka, josta on muita alaluokkia, jotka hy\u00f6dynt\u00e4v\u00e4t t\u00e4t\u00e4 toimintoa. T\u00e4m\u00e4 kertoo meille, ett\u00e4 meid\u00e4n on k\u00e4ytett\u00e4v\u00e4 suojattua n\u00e4kyvyyden muokkaajaa.<\/p>\n<p>Tied\u00e4mme my\u00f6s, ett\u00e4 k\u00e4sittelemme WordPressin nonce-arvoa ja siihen liittyv\u00e4\u00e4 toimintaa. T\u00e4m\u00e4 tarkoittaa, ett\u00e4 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-function-signature-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">funktion allekirjoitus n\u00e4ytt\u00e4\u00e4 suunnilleen t\u00e4lt\u00e4<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action);<\/code><\/pre>\n<h3>2 Puhdista tiedot, varmista, ettei ole mit\u00e4\u00e4n<\/h3>\n<p>Kaikkien palvelimelle l\u00e4hetettyjen tietojen osalta tied\u00e4mme, ett\u00e4 meid\u00e4n on tarkistettava, ett\u00e4 tiedot on asetettu, ja jos on, meid\u00e4n on desinfioitava tiedot.<\/p>\n<p>T\u00e4m\u00e4 tarkoittaa, ett\u00e4 tarvitsemme seuraavat toiminnot:<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.isset.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">isset<\/a><\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strip-tags.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">strip_tags<\/a><\/li>\n<li><strong><a href=\"https:\/\/php.net\/manual\/en\/function.stripslashes.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">viiltoja<\/a><\/strong><\/li>\n<\/ul>\n<p>Tied\u00e4mme my\u00f6s, ett\u00e4 meid\u00e4n on tarkistettava nonce, joten tarvitsemme my\u00f6s <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 Toimiva ensimm\u00e4inen passi<\/h3>\n<p>T\u00e4m\u00e4n toiminnon toimiva ensimm\u00e4inen l\u00e4pimeno voi n\u00e4ytt\u00e4\u00e4 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-verify-request-1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4lt\u00e4:<\/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>Mutta ent\u00e4 jos joku jakaa tietoja, joille on l\u00e4hetetty <strong>POST<\/strong> &#8211; pyynt\u00f6 (verrattuna <strong>GET<\/strong> &#8211; pyynt\u00f6\u00f6n)? Sitten voimme muokata funktiota n\u00e4ytt\u00e4m\u00e4\u00e4n <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-02-verify-request-2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4lt\u00e4:<\/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>Ja t\u00e4m\u00e4 riitt\u00e4isi. Mutta jos todella haluamme tietyn funktion olevan mahdollisimman puhdas, voimme hajottaa t\u00e4m\u00e4n viel\u00e4 pidemm\u00e4lle.<\/p>\n<h3>4 Toiminto jokaiseen tarkoitukseen<\/h3>\n<p>Yll\u00e4 olevan koodin perusteella tied\u00e4mme, ett\u00e4 meid\u00e4n on k\u00e4sitelt\u00e4v\u00e4 sek\u00e4 GET-pyynn\u00f6t ett\u00e4 POST-pyynn\u00f6t. PHP tarjoaa <strong>filter_input<\/strong> -funktion, joka on hy\u00f6dyllinen, helpompi lukea (no, t\u00e4m\u00e4 on subjektiivista), mutta my\u00f6s l\u00e4p\u00e4isee useita koodin laatutarkastuksia.<\/p>\n<p>Lis\u00e4ksi voimme k\u00e4ytt\u00e4\u00e4 <strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Factory_method_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">yksinkertaista tehdastyyppist\u00e4<\/a><\/strong> funktiota erottamaan logiikka erillisiksi funktioiksi, kuten t\u00e4m\u00e4:<\/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=\"Suojattu WordPress-lomakkeen l\u00e4hetys\" ><\/a><\/p>\n<p>Ensin meid\u00e4n on kirjoitettava kaksi erillist\u00e4 funktiota \u2013 yksi <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-03-verify-post-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">POST-pyynt\u00f6\u00e4 varten:<\/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>Ja yksi <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-04-verify-get-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">GET-pyynt\u00f6\u00e4 varten:<\/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>Sitten voimme sitoa sen yhteen <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-05-verify-request-factory-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">alkuper\u00e4iseen funktioon seuraavasti:<\/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>Saapuvien pyynt\u00f6jen puhdas hallinta<\/h2>\n<p>Ehk\u00e4 t\u00e4m\u00e4 n\u00e4ytt\u00e4\u00e4 monimutkaiselta tavalta k\u00e4sitell\u00e4 yksinkertaista ratkaisua, kun otetaan huomioon alkuper\u00e4inen jaettu koodisarja.<\/p>\n<p>Se on varmasti mahdollista varsinkin, jos olet ajan rajoitusten alla tai et v\u00e4lit\u00e4 niin paljon asioiden hajottamisesta pienimpiin mahdollisiin atomikomponentteihin (tai jopa testattaviin).<\/p>\n<p>Mutta jos haluat kirjoittaa oliopohjaista koodia mahdollisimman tarkasti, ehk\u00e4 t\u00e4m\u00e4 prosessi auttaa juuri siin\u00e4.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e4m\u00e4 koskee enemm\u00e4n suojattua WordPress-lomakkeen l\u00e4hett\u00e4mist\u00e4 asetussivulta tai asetussivulta kuin se on mallista tuleva lomake.<\/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":[895,843,803,864],"tags":[1166],"class_list":["post-230970","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koodi","category-opetusohjelmia","category-php-5","category-wordpress-5","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230970","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=230970"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230970\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/236238"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=230970"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=230970"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=230970"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}