REST API WordPress nâng cao: xác thực qua nonce, gửi file, hook vào API mặc định

Sau khi đã biết cách tạo route riêng và xử lý POST với permission_callback, bước tiếp theo là làm việc với các tình huống nâng cao như xác thực qua nonce cho frontend JS, gửi file qua REST API, và hook vào API mặc định của WordPress.

REST API WordPress nâng cao: xác thực qua nonce, gửi file, hook vào API mặc định

1. Xác thực REST API bằng nonce (cho frontend JS)

Mặc định WordPress không tự cho phép người dùng frontend gọi các route yêu cầu quyền. Để xác thực request AJAX/Fetch, bạn cần:

  • Tạo nonce với wp_create_nonce('wp_rest')
  • Gửi kèm header X-WP-Nonce trong request

Ví dụ: chèn nonce vào JS

// Trong plugin hoặc theme
wp_localize_script('your-js', 'MyAPI', [
    'nonce' => wp_create_nonce('wp_rest'),
]);

Fetch từ JS (frontend):

fetch('/wp-json/demo/v1/secure', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-WP-Nonce': MyAPI.nonce
  },
  body: JSON.stringify({ foo: 'bar' })
});

Trong PHP, bạn chỉ cần:

'permission_callback' => function () {
    return current_user_can('edit_posts'); // Hoặc bất kỳ quyền nào bạn chọn
}

WordPress sẽ tự kiểm tra nonce và user hiện tại, trả 401 nếu không hợp lệ.

2. Gửi file qua REST API (ví dụ: upload ảnh)

REST API mặc định không hỗ trợ upload file qua JSON, nhưng có thể dùng FormData trong JavaScript để gửi ảnh như sau:

JavaScript gửi ảnh qua FormData:

const formData = new FormData();
formData.append('image', fileInput.files[0]);

fetch('/wp-json/demo/v1/upload', {
  method: 'POST',
  headers: {
    'X-WP-Nonce': MyAPI.nonce
  },
  body: formData
});

PHP xử lý file:

add_action('rest_api_init', function () {
    register_rest_route('demo/v1', '/upload', [
        'methods'             => 'POST',
        'callback'            => 'demo_api_upload_image',
        'permission_callback' => function () {
            return current_user_can('upload_files');
        },
    ]);
});

function demo_api_upload_image($request) {
    if (empty($_FILES['image'])) {
        return new WP_Error('no_file', 'Không có file nào được gửi.', ['status' => 400]);
    }

    $file = $_FILES['image'];
    $result = media_handle_upload('image', 0);

    if (is_wp_error($result)) {
        return $result;
    }

    return [
        'status'  => 'success',
        'id'      => $result,
        'url'     => wp_get_attachment_url($result),
    ];
}

Nhớ include file sau nếu dùng media_handle_upload():

require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';

3. Hook vào REST API mặc định của WordPress

WordPress đã có nhiều route sẵn như /wp/v2/posts, /comments… Bạn có thể hook vào kết quả trả về để thêm trường tùy ý.

Thêm trường “view_count” vào API post:

add_action('rest_api_init', function () {
    register_rest_field('post', 'view_count', [
        'get_callback' => function ($object) {
            return (int) get_post_meta($object['id'], '_init_view_count', true);
        },
        'schema' => [
            'type' => 'integer',
            'context' => ['view'],
        ],
    ]);
});

Sau khi thêm, gọi /wp-json/wp/v2/posts sẽ có thêm trường view_count.

4. Một số mẹo nâng cao khác

  • REST API có thể dùng namespace riêng để tách các plugin khác nhau (ví dụ init/v1)
  • Tránh ghi đè lên wp/v2 nếu không cần, sẽ gây lỗi xung đột
  • Có thể dùng filter rest_pre_dispatch để can thiệp mọi route
  • Có thể kết hợp với JWT, cookie, hoặc OAuth nếu muốn xác thực ở cấp độ cao hơn

Kết luận

REST API là phần không thể thiếu nếu bạn muốn tạo plugin hiện đại, frontend JS tách biệt, hoặc các hệ thống như dashboard người dùng, AJAX form, bình luận, theo dõi tiến trình… Với các kỹ thuật như xác thực nonce, upload file, mở rộng API mặc định – bạn đã sẵn sàng làm mọi thứ chuyên nghiệp hơn mà không cần jQuery hay admin-ajax.php nữa.

Bắt đầu đơn giản, sau đó hãy dần dần chuẩn hóa mọi thứ theo hướng API-driven – đó là tương lai đúng của WordPress.

Bình luận


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...