Blog
Bezpečný vývoj REST API ve WordPressu: Praktický průvodce
Naučte se vytvářet vlastní REST API koncové body ve WordPressu s důrazem na bezpečnost, validaci a výkon. Tento průvodce pokrývá registraci tras, sanitaci vstupů, callbacky oprávnění, použití nonce a strategie ukládání do mezipaměti, aby vaše API bylo robustní a efektivní.

Shrnutí
WordPress REST API je výkonný nástroj pro rozšíření funkcionality vašeho webu, ale špatně implementované koncové body mohou vystavit váš web bezpečnostním rizikům. Tento článek se zabývá běžným problémem nezabezpečených vlastních API tras a poskytuje krok za krokem průvodce vytvářením bezpečných koncových bodů. Naučíte se, jak správně registrovat trasy, validovat a sanitizovat uživatelské vstupy, vynucovat oprávnění pomocí callbacků a chránit proti CSRF pomocí nonce. Dále se budeme věnovat technikám optimalizace výkonu, jako je ukládání do mezipaměti a použití argumentů WP_Query. Dodržováním těchto postupů vytvoříte REST koncové body, které jsou bezpečné a výkonné. Součástí jsou příklady z praxe a upozornění, která vám pomohou vyhnout se typickým nástrahám.
WordPress REST API otevírá vývojářům svět možností, od provozování headless frontendů po umožnění vlastních integrací. S velkou mocí však přichází velká odpovědnost – každý vlastní koncový bod, který vytvoříte, je potenciálním vstupním bodem pro útoky, pokud není řádně zabezpečen. Tento průvodce vás provede vytvářením bezpečných REST API koncových bodů ve WordPressu se zaměřením na registraci, zpracování vstupů, oprávnění, nonce a výkon. Na konci budete mít opakovatelný proces pro vytváření koncových bodů, které jsou bezpečné, efektivní a udržovatelné.
Registrace trasy: Základ
Každý REST koncový bod začíná funkcí register_rest_route(). Mnoho vývojářů však vynechává klíčové parametry, které vynucují bezpečnost. Při registraci trasy musíte zadat namespace (obvykle slug vašeho pluginu/šablony), trasu a pole možností zahrnující callback, permission_callback a args pro validaci. Vždy používejte unikátní namespace, aby nedošlo ke kolizím s jinými pluginy. Například:
add_action('rest_api_init', function () {
register_rest_route('myplugin/v1', '/secure-data', array(
'methods' => 'GET',
'callback' => 'myplugin_secure_data_callback',
'permission_callback' => 'myplugin_permission_check',
'args' => array(
'user_id' => array(
'required' => true,
'validate_callback' => function($param) { return is_numeric($param); },
'sanitize_callback' => 'absint',
),
),
));
});
Všimněte si pole args – zde definujete pravidla pro validaci a sanitizaci. Explicitním deklarováním očekávaných parametrů s callbacky zabráníte tomu, aby se poškozená data dostala k hlavnímu callbacku. To je klíčový princip Zvládnutí WordPress hooks (i když aplikovaný na REST). Vždy definujte args i pro jednoduché koncové body; dokumentuje to očekávaný vstup a zachytí překlepy brzy.
Validace a sanitizace vstupů: Uzamkněte data
Zpracování vstupů je nejčastějším zdrojem zranitelností. WordPress poskytuje dvě vrstvy: validaci (splňuje data kritéria?) a sanitizaci (vyčištění dat). Použijte validate_callback k odmítnutí špatného vstupu před zpracováním. Například pro přijetí pouze kladných celých čísel:
'validate_callback' => function($param) { return is_numeric($param) && $param > 0; }
Poté použijte sanitize_callback k vyčištění hodnoty, např. absint, sanitize_text_field, sanitize_email. Vyhněte se použití wp_kses_post, pokud nepotřebujete HTML; preferujte přísnější sanitizéry. Pro pole parametrů mapujte každou položku pomocí array_map('sanitize_text_field', $param).
Pokud nechcete definovat plné args předem, můžete stále sanitizovat uvnitř callbacku:
$user_id = isset($request['user_id']) ? absint($request['user_id']) : 0;
Ale to je méně samodokumentující. Pro složité koncové body preferujte inline validační callbacky.
Callbacky oprávnění: Kdo má přístup?
Každý koncový bod musí mít permission_callback. Pokud chybí, WordPress stále vyžaduje callback, ale ve starších verzích bude výchozí __return_true – což je hrozné pro bezpečnost. Vždy vracejte boolean nebo objekt WP_Error. Běžné vzory:
function myplugin_permission_check() {
if (!current_user_can('edit_posts')) {
return new WP_Error('rest_forbidden', 'You cannot access this resource.', array('status' => 403));
}
return true;
}
Pro přístup založený na rolích použijte current_user_can() s capabilities jako manage_options, edit_others_posts nebo vlastní capabilities. Vyhněte se pevnému kódování názvů rolí (např. 'administrator'); používejte capabilities, aby si vlastník webu mohl upravit oprávnění pomocí pluginů. Pro veřejné koncové body (např. načítání publikovaných příspěvků) nastavte 'permission_callback' => '__return_true' pouze tehdy, když je to nezbytně nutné – a vždy doplňte o řádná omezení dat v callbacku.
Ochrana proti CSRF pomocí nonce
Zatímco REST API požadavky kontrolují platný nonce pro uživatele přihlášené pomocí cookies, vaše koncové body mohou být přístupné z externích klientů (např. mobilních aplikací), které cookies nepoužívají. Pokud váš koncový bod upravuje data, zajistěte jeho ochranu proti Cross-Site Request Forgery. Pro interní použití pošlete nonce prostřednictvím wp_rest nonce (automaticky zpracováno middlewarem REST API). Pro externí koncové body můžete implementovat autentizaci na základě tokenů nebo použít WordPress nonce v hlavičce požadavku. Příklad s JavaScriptem:
wp.apiFetch({ path: '/myplugin/v1/add-post', method: 'POST', data: { title: 'New' } });
Toto používá vestavěný nonce. Pokud vytváříte vlastní integraci, vygenerujte nonce pomocí wp_create_nonce('wp_rest') a zahrňte jej do hlavičky X-WP-Nonce.
Výkon: Ukládání do mezipaměti a optimalizace
Bezpečné koncové body mohou být stále pomalé. Použijte transienty k ukládání náročných dotazů do mezipaměti:
$cache_key = 'myplugin_recent_posts_' . $user_id;
$posts = get_transient($cache_key);
if (false === $posts) {
$posts = get_posts(array('author' => $user_id, 'posts_per_page' => 10));
set_transient($cache_key, $posts, HOUR_IN_SECONDS);
}
Ukládejte do mezipaměti pro každého uživatele, pokud se data liší. Také implementujte stránkování pomocí $request->get_param('page') a offset, abyste nepřetížili databázi. Omezte vracená pole – použijte ['ID', 'post_title'] místo vracení všech dat příspěvku. Pro koncové body s vysokým provozem zvažte ukládání do objektové mezipaměti pomocí Redis.
Příklad z praxe: Bezpečný koncový bod pro nejnovější příspěvky
Pojďme vytvořit koncový bod, který vrací názvy nejnovějších příspěvků pro dané ID uživatele, přístupný pouze uživatelům s edit_posts. Kompletní kód:
add_action('rest_api_init', function () {
register_rest_route('myplugin/v1', '/user-posts/(?P<user_id>\d+)', array(
'methods' => 'GET',
'callback' => 'myplugin_user_posts_callback',
'permission_callback' => function() { return current_user_can('edit_posts'); },
'args' => array(
'user_id' => array(
'required' => true,
'validate_callback' => function($param) { return is_numeric($param); },
'sanitize_callback' => 'absint',
),
),
));
});
function myplugin_user_posts_callback($request) {
$user_id = $request->get_param('user_id');
$cache_key = 'myplugin_user_posts_' . $user_id;
$posts = get_transient($cache_key);
if (false === $posts) {
$query = new WP_Query(array(
'author' => $user_id,
'post_status' => 'publish',
'fields' => 'ids',
));
$posts = $query->posts;
if (!empty($posts)) {
$titles = array();
foreach ($posts as $post_id) {
$titles[] = get_the_title($post_id);
}
set_transient($cache_key, $titles, 6 * HOUR_IN_SECONDS);
return new WP_REST_Response($titles, 200);
}
return new WP_REST_Response(array(), 200);
}
return new WP_REST_Response($posts, 200);
}
Tento koncový bod validuje user_id, kontroluje oprávnění, ukládá výsledky do mezipaměti a vrací čistá data.
Upozornění a časté chyby
- Nedůvěřujte
$_GETnebo$_POSTuvnitř REST callbacků; vždy používejte$request->get_params(). - Validujte oprávnění i u GET koncových bodů, které odhalují citlivá data (např. e-maily uživatelů).
- Zpracování chyb: Používat
wp_send_json_error()uvnitř callbacků? Ne – vraťteWP_ErrorneboWP_REST_Responsepro konzistenci. - Testování: Používejte nástroje jako Postman nebo curl s nonce hlavičkami k simulaci požadavků.
- Global $wpdb: Obalte databázové dotazy do
$wpdb->prepare(), abyste zabránili SQL injection. - Omezování rychlosti: Zvažte implementaci vlastního omezování rychlosti pomocí transientů, pokud je koncový bod veřejný.
Závěr
Vytvoření bezpečného WordPress REST koncového bodu vyžaduje pozornost na každé vrstvě: registrace trasy, zpracování vstupů, oprávnění, nonce a výkon. Dodržováním postupů uvedených zde – zejména definováním args s validačními/sanitizačními callbacky, vždy nastavením permission_callback, ukládáním náročných dotazů do mezipaměti a používáním nonce – vytvoříte koncové body, které obstojí při kontrole. Aplikujte tyto vzory na každou vlastní trasu, kterou napíšete, a důkladně testujte s autentizovanými i neautentizovanými požadavky. Pro další čtení o souvisejících bezpečnostních tématech si prohlédněte našeho průvodce Bezpečnost a výkon WordPress pluginů. Nyní jděte a zabezpečte své API.
Sources (5)
- WordPress Architecture: A Complete Guide - Liquid Web
- Essential WordPress Plugin Development Best Practices - Pixel Fish
- Best Practices – Plugin Handbook - WordPress Developer Resources
- A Guide To Understanding WordPress Architecture - Pressable
- Modern approach to WordPress plugin development | by Gabriele Bellini - Medium
