admin管理员组

文章数量:1122846

I am creating a headless Wordpress website. Wordpress backend (port 8888), VueJS frontend (port 8081). Data is loaded via REST API. This works fine.

Now I want to implement the preview-functionality. Therefore I wrote some code to get a JWT token to authenticate. After that I want to get the draft/preview data by requesting this URL (with bearer token header):

http://localhost:8888/wp-json/wp/v2/pages/11?preview_id=11&_wpnonce=01c024a8ed&preview=true&acf_format=standard&status=draft

This fails because of a nonce-validation error. I looked into the wp_create_nonce and wp_verify_nonce functions, and found out they use a token by calling wp_get_session_token(). When I click the preview button in the Wordpress backend, it uses the session token from the active session to generate the nonce. This session, however, is different from the session that is created by the JWT authentication. Therefore the nonces are different and the validation of the nonce fails.

How can I solve this issue? Overwriting the wp_create_nonce and wp_verify_nonce functions and leaving out the wp_get_session_token() doesn't feel like a good solution.

Thanks!

I am creating a headless Wordpress website. Wordpress backend (port 8888), VueJS frontend (port 8081). Data is loaded via REST API. This works fine.

Now I want to implement the preview-functionality. Therefore I wrote some code to get a JWT token to authenticate. After that I want to get the draft/preview data by requesting this URL (with bearer token header):

http://localhost:8888/wp-json/wp/v2/pages/11?preview_id=11&_wpnonce=01c024a8ed&preview=true&acf_format=standard&status=draft

This fails because of a nonce-validation error. I looked into the wp_create_nonce and wp_verify_nonce functions, and found out they use a token by calling wp_get_session_token(). When I click the preview button in the Wordpress backend, it uses the session token from the active session to generate the nonce. This session, however, is different from the session that is created by the JWT authentication. Therefore the nonces are different and the validation of the nonce fails.

How can I solve this issue? Overwriting the wp_create_nonce and wp_verify_nonce functions and leaving out the wp_get_session_token() doesn't feel like a good solution.

Thanks!

Share Improve this question edited Apr 4, 2024 at 12:27 klaaskox asked Mar 29, 2024 at 10:32 klaaskoxklaaskox 1112 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

In a headless WordPress setup where you are using JWT for authentication, the standard nonce mechanism provided by wp may not directly fit your needs, especially when dealing with preview functionality. The nonce generated by wp is typically tied to the users session, which is not compatible with JWT authentication.

One approach to solve this issue is to create a custom nonce mechanism that works with your JWT authentication

// Step 1: Custom endpoint to generate nonce
add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/nonce', array(
        'methods' => 'GET',
        'callback' => 'generate_custom_nonce',
        'permission_callback' => function () {
            return current_user_can('read'); // Adjust permission as needed
        }
    ));
});

function generate_custom_nonce(WP_REST_Request $request) {
    // Generate nonce based on user's JWT token
    $user_id = get_current_user_id();
    $nonce = wp_create_nonce('custom_action_' . $user_id);
    
    return rest_ensure_response($nonce);
}

// Step 2: Validate nonce in requests
add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/preview', array(
        'methods' => 'GET',
        'callback' => 'get_preview_data',
        'permission_callback' => function () {
            return current_user_can('read'); // Adjust permission as needed
        }
    ));
});

function get_preview_data(WP_REST_Request $request) {
    $nonce = $request->get_header('X-Custom-Nonce'); // Get nonce from header
    $valid_nonce = wp_verify_nonce($nonce, 'custom_action_' . get_current_user_id());
    
    if (!$valid_nonce) {
        return new WP_Error('invalid_nonce', 'Invalid nonce.', array('status' => 403));
    }

    // Proceed to fetch preview data
    // Your code to fetch and return preview data
}

本文标签: Nonce validation in REST API