Nem csak a látvány számít: Biztonságos WordPress REST API végpontok készítése
Az ötleted ragyogó: a saját, egyedi admin felületedet vagy mobil appodat akarod a WordPress adatbázisodhoz kapcsolni egy REST API-n keresztül. Megvan a kreativitás, de egy kritikus kérdés merül fel: Hogyan zárjuk le az ajtót, hogy ne jöhessen be aki nem hívott? A WordPress REST API alapból erős, de saját végpontok készítésekor a biztonság teljes mértékben a mi felelősségünk. Ma ezt a láthatatlan, de létfontosságú réteget nézzük meg együtt.
Miért nem elég a sima „Hello World” végpont?
Amikor elkezdünk API végpontot készíteni, a legtöbb tutorial a minimális példával indul: regisztrálj egy route-ot, köss hozzá egy függvényt, és küldj vissza valami JSON-t. Ilyen egyszerűen meg is van a sebezhetőség.
// FIGYELMEZTETÉS: EZ BIZTONSÁGI RÉS!
add_action('rest_api_init', function () {
register_rest_route('sajat/v1', '/adat', [
'methods' => 'GET',
'callback' => function() {
return ['titkos_adat' => 'Ez bárki számára látható!'];
},
]);
});Ez a kód mindenki számára elérhetővé teszi az adatot – bejelentkezett felhasználó, vendég, vagy akár egy rosszindulatú script számára egy másik domainről. A gyakorlatban ez olyan, mintha a bankszámlakivonatodat a bejárati ajtó elé tennéd.
Az első védőfal: A jogosultságkezelő callback
A WordPress megoldása elegáns: minden route regisztrálásakor megadhatunk egy permission_callback függvényt. Ez a kapuőr, aki dönti el, hogy a kérés továbbhaladhat-e.
add_action('rest_api_init', function () {
register_rest_route('sajat/v1', '/profil', [
'methods' => 'GET',
'callback' => 'sajat_api_lekeres',
'permission_callback' => function () {
return is_user_logged_in(); // Csak bejelentkezett felhasználók
}
]);
register_rest_route('sajat/v1', '/beallitasok', [
'methods' => 'POST',
'callback' => 'sajat_api_frissites',
'permission_callback' => function () {
return current_user_can('manage_options'); // Csak adminisztrátorok
}
]);
});
function sajat_api_lekeres() {
$current_user = wp_get_current_user();
return [
'nev' => $current_user->display_name,
'email' => $current_user->user_email
];
}A permission_callback mindig egy függvényt vagy anonym függvényt vár, ami true vagy false értéket ad vissza. Itt használhatjuk a WordPress beépített funkcióit (current_user_can, is_user_logged_in), de akár saját, komplex logikát is implementálhatunk.
Gyakori buktatók, amikbe én is belebotlottam
1. A hiányzó permission_callback: A legnagyobb hiba, ha egyáltalán nem adunk meg ilyet. A WordPress 5.5 óta a REST API kikényszeríti, hogy legyen permission_callback. Ha hiányzik, a fejlesztői konzolban figyelmeztetést kapsz, és gyakran a végpontod egyáltalán nem fog működni.
2. Túl komplex logika a callbackben: A permission_callback célja a hozzáférés eldöntése, ne a teljes üzleti logikát pakoljuk bele. Ha bonyolult ellenőrzéseket végzünk (pl. külső API hívás), az lassítja az összes kérést.
3. Nonce tokenek elfelejtése: A wp_create_nonce() és wp_verify_nonce() páros nem csak formumegjelenítésekhez kell. Ha olyan műveletet végzünk, ami állapotot módosít (POST, PUT, DELETE), a nonce tokenek létfontosságúak a CSRF támadások kivédésére. Különösen fontosak, ha a frontend jQuery-vel készül.
Egy komplett példa: Admin beállítások biztonságos mentése
Képzeljük el, hogy van egy egyedi admin panelünk, ahol csak „editor” szerepkörű felhasználók módosíthatnak beállításokat. Így nézhet ki a backend rész:
add_action('rest_api_init', function () {
register_rest_route('portfolio/v1', '/social', [
'methods' => 'POST',
'callback' => 'mentes_social_links',
'permission_callback' => 'ellenoriz_social_mentes_jogot'
]);
});
function ellenoriz_social_mentes_jogot($request) {
// 1. Alap: legyen bejelentkezett
if (!is_user_logged_in()) {
return false;
}
// 2. Legyen editor vagy annál magasabb jogosultság
if (!current_user_can('edit_pages')) {
return false;
}
// 3. Ellenőrizzük a nonce-t (a frontendről kell jönnie)
$nonce = $request->get_header('X-WP-Nonce');
if (!wp_verify_nonce($nonce, 'wp_rest')) {
return false;
}
return true;
}
function mentes_social_links($request) {
$parameters = $request->get_json_params();
// Input tisztítása - soha ne bízzunk a felhasználói adatokban
$facebook = sanitize_text_field($parameters['facebook_url'] ?? '');
$twitter = esc_url_raw($parameters['twitter_url'] ?? '');
update_option('portfolio_social_facebook', $facebook);
update_option('portfolio_social_twitter', $twitter);
return [
'success' => true,
'message' => 'Beállítások frissítve'
];
}És a frontend oldal (egy egyszerű admin panel része), ahol Bootstrap segítségével készült a felület, és jQuery kezeli a kérést:
<div class="container mt-4">
<div class="card">
<div class="card-header">
<h5>Közösségi média linkek</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">Facebook URL</label>
<input type="text" class="form-control" id="facebook-url">
</div>
<div class="mb-3">
<label class="form-label">Twitter URL</label>
<input type="text" class="form-control" id="twitter-url">
</div>
<button id="mentes-gomb" class="btn btn-primary">Mentés</button>
<div id="uzenet" class="mt-3"></div>
</div>
</div>
</div>
<style>
/* SCSS alapú stílus – jobb strukturáltság érdekében */
.card {
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
&-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 10px 10px 0 0 !important;
}
}
</style>
<script>
jQuery(document).ready(function($) {
$('#mentes-gomb').on('click', function() {
let gomb = $(this);
gomb.prop('disabled', true).text('Mentés...');
$.ajax({
url: '/wp-json/portfolio/v1/social',
method: 'POST',
beforeSend: function(xhr) {
// A nonce-t a wp_localize_script-ből is kaphatnánk
xhr.setRequestHeader('X-WP-Nonce', wpApiSettings.nonce);
},
contentType: 'application/json',
data: JSON.stringify({
facebook_url: $('#facebook-url').val(),
twitter_url: $('#twitter-url').val()
}),
success: function(valasz) {
$('#uzenet').html(
'<div class="alert alert-success">' + valasz.message + '</div>'
);
},
error: function() {
$('#uzenet').html(
'<div class="alert alert-danger">Hiba történt a mentés során!</div>'
);
},
complete: function() {
gomb.prop('disabled', false).text('Mentés');
}
});
});
});
</script>A végső összegzés: A biztonság mentalitás kérdése
A biztonságos REST API végpontok nem egy egyszeri beállítás, hanem egy mentalitás. Mindig tedd fel a kérdést: „Ki számára akarom elérhetővé tenni ezt az adatot/műveletet?” A válasz alapján válaszd ki a megfelelő szűrőket:
– Nyilvános adatok: permission_callback: '__return_true'
– Bejelentkezett felhasználók: is_user_logged_in() ellenőrzés
– Specifikus jogosultság: current_user_can('capability')
– Egyedi logika: Saját callback a régebbi WordPress verziók kompatibilitásához
Ne feledd: a WordPress adatbázisodban a vállalkozásod szíve ver. A REST API egy hatalmas kapu, ami csodálatos lehetőségeket nyit meg – de pontosan ezért kell őrizni, mint a legfontosabb kincsedet. Szép kódolást és nyugodt éjszakákat (mert tudod, hogy az API-d védett)!