Blog
Sikker WordPress REST API-udvikling: En praktisk guide
Lær at bygge tilpassede REST API-endepunkter i WordPress med korrekt sikkerhed, validering og bedste praksis for ydeevne. Denne guide dækker rute registrering, input-sanitering, tilladelses-callbacks, nonce-brug og caching-strategier for at sikre, at dit API er både robust og effektivt.

Resumé
WordPress REST API er et kraftfuldt værktøj til at udvide din hjemmesides funktionalitet, men dårligt implementerede endepunkter kan udsætte din hjemmeside for sikkerhedssårbarheder. Denne artikel adresserer det almindelige problem med usikre tilpassede API-ruter ved at give en trin-for-trin guide til at bygge sikre endepunkter. Du lærer, hvordan du korrekt registrerer ruter, validerer og saniterer brugerinput, håndhæver tilladelser med callbacks og beskytter mod CSRF ved hjælp af nonces. Derudover dækker vi optimeringsteknikker som caching og brug af WP_Query-argumenter. Ved at følge disse praksisser skaber du REST-endepunkter, der både er sikre og performante. Virkelige eksempler og advarsler er inkluderet for at hjælpe dig med at undgå typiske faldgruber.
WordPress REST API åbner en verden af muligheder for udviklere, fra at drive headless frontends til at muliggøre tilpassede integrationer. Men med stor magt følger stort ansvar – ethvert tilpasset endepunkt, du opretter, er et potentielt indgangspunkt for angreb, hvis det ikke er ordentligt sikret. Denne guide fører dig gennem opbygning af sikre REST API-endepunkter i WordPress med fokus på registrering, inputhåndtering, tilladelser, nonces og ydeevne. Til sidst vil du have en gentagelig proces til at oprette endepunkter, der er sikre, effektive og vedligeholdelsesvenlige.
Registrering af en rute: Fundamentet
Hvert REST-endepunkt starter med register_rest_route(). Men mange udviklere springer kritiske parametre over, der håndhæver sikkerhed. Når du registrerer en rute, skal du angive et navnerum (typisk dit plugin/tema-slug), en rute og en række muligheder inklusive callback, permission_callback og args til validering. Brug altid et unikt navnerum for at undgå kollisioner med andre plugins. For eksempel:
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',
),
),
));
});
Bemærk args-arrayet – det er her, du definerer validerings- og saniteringsregler. Ved eksplicit at erklære forventede parametre med callbacks forhindrer du misdannede data i nogensinde at nå din hoved-callback. Dette er et nøgleprincip i Mestring af WordPress Hooks (dog anvendt på REST). Definer altid args selv for simple endepunkter; det dokumenterer forventet input og fanger tastefejl tidligt.
Inputvalidering og -sanitering: Lås data ned
Inputhåndtering er den mest almindelige kilde til sårbarheder. WordPress giver to lag: validering (opfylder data kriterierne?) og sanitering (rens data). Brug validate_callback til at afvise dårlig input før behandling. For eksempel for kun at acceptere positive heltal:
'validate_callback' => function($param) { return is_numeric($param) && $param > 0; }
Brug derefter sanitize_callback til at rense værdien, f.eks. absint, sanitize_text_field, sanitize_email. Undgå at bruge wp_kses_post medmindre du har brug for HTML; foretræk strengere saniteringsfunktioner. For array-parametre, map over hvert element med array_map('sanitize_text_field', $param).
Hvis du ikke vil definere fulde args på forhånd, kan du stadig saniter inde i din callback:
$user_id = isset($request['user_id']) ? absint($request['user_id']) : 0;
Men dette er mindre selv-dokumenterende. For komplekse endepunkter, foretræk inline valideringscallbacks.
Tilladelses-callbacks: Hvem får adgang?
Hvert endepunkt skal have en permission_callback. Hvis den mangler, kræver WordPress stadig en callback, men vil som standard bruge __return_true i ældre versioner – forfærdeligt for sikkerheden. Returner altid en boolean eller et WP_Error-objekt. Almindelige mønstre:
function myplugin_permission_check() {
if (!current_user_can('edit_posts')) {
return new WP_Error('rest_forbidden', 'Du har ikke adgang til denne ressource.', array('status' => 403));
}
return true;
}
For rollebaseret adgang, brug current_user_can() med capabilities som manage_options, edit_others_posts eller tilpassede capabilities. Undgå at hardcode rollenavne (f.eks. 'administrator'); brug capabilities så hjemmesideejeren kan justere via plugins. For offentlige endepunkter (f.eks. hentning af publicerede indlæg), sæt 'permission_callback' => '__return_true' kun når absolut nødvendigt – og kombiner altid med ordentlige databegrænsninger i callback'en.
CSRF-beskyttelse med Nonces
Selvom REST API-anmodninger tjekker for en gyldig nonce for cookie-autentificerede brugere, kan dine endepunkter tilgås fra eksterne klienter (f.eks. mobilapps), der ikke bruger cookies. Hvis dit endepunkt ændrer data, skal du sikre, at det er beskyttet mod Cross-Site Request Forgery. Til intern brug sendes en nonce via wp_rest nonce (håndteres automatisk af REST API-mellemwaren). For eksterne endepunkter kan du implementere tokenbaseret autentificering eller bruge WordPress nonces i anmodningsheaderen. Eksempel med JavaScript:
wp.apiFetch({ path: '/myplugin/v1/add-post', method: 'POST', data: { title: 'Ny' } });
Dette bruger den indbyggede nonce. Hvis du bygger en tilpasset integration, generer en nonce via wp_create_nonce('wp_rest') og inkluder den i X-WP-Nonce headeren.
Ydeevne: Caching og optimering
Sikre endepunkter kan stadig være langsomme. Brug transients til at cache dyre forespørgsler:
$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);
}
Cache per bruger hvis data varierer. Implementer også paginering ved hjælp af $request->get_param('page') og offset for at undgå at overbelaste databasen. Begræns returnerede felter – brug ['ID', 'post_title'] i stedet for at returnere alle indlægsdata. For høj-trafik endepunkter, overvej objekt-caching med Redis.
Virkeligt eksempel: Sikkert endepunkt for seneste indlæg
Lad os bygge et endepunkt, der returnerer seneste indlægstitler for et givet bruger-ID, kun tilgængeligt for brugere med edit_posts. Fuldstændig kode:
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);
}
Dette endepunkt validerer user_id, tjekker tilladelser, cacher resultater og returnerer rene data.
Forbehold & almindelige faldgruber
- Stol ikke på
$_GETeller$_POSTinde i REST-callbacks; brug altid$request->get_params(). - Valider tilladelser selv for GET-endepunkter, der eksponerer følsomme data (f.eks. bruger-e-mails).
- Fejlhåndtering: Brug
wp_send_json_error()inde i callbacks? Nej – returner etWP_ErrorellerWP_REST_Responsefor konsistens. - Test: Brug værktøjer som Postman eller curl med nonce-headere til at simulere anmodninger.
- Global $wpdb: Indpak databaseforespørgsler i
$wpdb->prepare()for at forhindre SQL-injektion. - Rate limiting: Overvej at implementere brugerdefineret rate limiting ved hjælp af transients, hvis endepunktet er offentligt.
Konklusion
At bygge et sikkert WordPress REST-endepunkt kræver opmærksomhed på hvert lag: ruteregistrering, inputhåndtering, tilladelser, nonces og ydeevne. Ved at følge de praksisser, der er beskrevet her – især at definere args med validerings-/saniteringscallbacks, altid sætte en permission_callback, cache dyre forespørgsler og bruge nonces – skaber du endepunkter, der kan modstå granskning. Anvend disse mønstre på hver tilpasset rute, du skriver, og test grundigt med både autentificerede og uautentificerede anmodninger. For yderligere læsning om relaterede sikkerhedsemner, se vores guide om WordPress Plugin Sikkerhed & Ydeevne. Gå nu i gang med at sikre dit 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
