Hàm wp_get_cản_user () không hoạt động trong chức năng gọi lại API còn lại


8

Hãy xem xét các lớp sau.

<?php
class MCQAcademy_Endpoint extends WP_REST_Controller {

    /**
     * Register the routes for the objects of the controller.
     */
    public function register_routes() {
        $version = '1';
        $namespace = 'custompath/v' . $version;
        $base = 'endpointbase';

        register_rest_route(
            $namespace,
            '/' . $base,
            array(
                array(
                    'methods'         => WP_REST_Server::READABLE,
                    'callback'        => array( $this, 'get_items' ),
                    'permission_callback' => array( $this, 'get_items_permissions_check' ),
                    'args'            => array(),
                )
            )
        );
    }

    /**
     *
     */
    public function get_items( $request ) {
        $rs = array(
            'data' => array(),
            'request' => array(
                'lang' => 'en',
            ),
        );

        $args = array();
        $items = get_posts( $args );

        foreach( $items as $item ) {
            $itemdata = $this->prepare_item_for_response( $item, $request );
            $rs['data'][] = $this->prepare_response_for_collection( $itemdata );
        }

        $rs['wp_get_current_user'] = wp_get_current_user(); // Does not output as expected

        return new WP_REST_Response( $rs, 200 );
    }

    /**
     * Check if a given request has access to get items
     */
    public function get_items_permissions_check( $request ) {
        return true; // to make readable by all
    }


    /**
     * Prepare the item for create or update operation
     */
    protected function prepare_item_for_database( $request ) {
        return $request;
    }

    /**
     * Prepare the item for the REST response
     */
    public function prepare_item_for_response( $item, $request ) {
        $data = array(
            'ID' => $item->ID,
            'post_content' => wpautop($item->post_content),
            'post_title' => $item->post_title,
        );

        return $data;
    }

    /**
     * Get the query params for collections
     */
    public function get_collection_params() {
        return array(
            'page'     => array(
                'description'        => 'Current page of the collection.',
                'type'               => 'integer',
                'default'            => 1,
                'sanitize_callback'  => 'absint',
            ),
            'per_page' => array(
                'description'        => 'Maximum number of items to be returned in result set.',
                'type'               => 'integer',
                'default'            => 10,
                'sanitize_callback'  => 'absint',
            ),
            'search'   => array(
                'description'        => 'Limit results to those matching a string.',
                'type'               => 'string',
                'sanitize_callback'  => 'sanitize_text_field',
            ),
        );
    }

    // Register our REST Server
    public function hook_rest_server(){
        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
    }
}

$myEndpoint = new MCQAcademy_Endpoint();
$myEndpoint->hook_rest_server();

Mọi thứ đều ổn, ngoại trừ việc gọi wp_get_current_user()hàm trong get_items()hàm trả về người dùng trống mặc dù người dùng đang logged inở trong trang web.

Câu trả lời:


10

Đăng nhập vào trang web của bạn không có nghĩa là người dùng được xác thực trong yêu cầu API REST, đó là lý do tại sao bạn không nhận được đúng người dùng hoặc Id = 0

Vui lòng xem các phương thức xác thực API REST trên các tài liệu:
https://developer.wordpress.org/rest-api/USE-the-rest-api/authentication/

Đối với các nhà phát triển thực hiện các yêu cầu Ajax thủ công, nonce sẽ cần phải được thông qua với mỗi yêu cầu. API sử dụng nonces với hành động được đặt thành wp_rest. Những thứ này sau đó có thể được chuyển đến API thông qua tham số dữ liệu _wpnonce (dữ liệu POST hoặc trong truy vấn cho các yêu cầu GET) hoặc thông qua tiêu đề X-WP-Nonce. Nếu không có thông tin nào được cung cấp, API sẽ đặt người dùng hiện tại thành 0, biến yêu cầu thành yêu cầu chưa được xác thực, ngay cả khi bạn đã đăng nhập vào WordPress.

Để xác thực từ xa, tôi khuyên dùng plugin JWT để bắt đầu nhanh:
https://es.wordpress.org/plugins/jwt-authentication-for-wp-rest-api/

Hoặc bạn có thể sử dụng những tài liệu được đề xuất trên các tài liệu:
https://developer.wordpress.org/rest-api/USE-the-rest-api/authentication/#authentication-plugins


1
Tôi cần id người dùng nếu người dùng đăng nhập vào trang web. Vì điểm cuối là mở, không cần kiểm tra sự cho phép.
Shah Alom

Dòng này trả về false luôn luôn mặc dù người dùng đã đăng nhập vào trang web. $rs['wp_get_current_user'] = is_user_logged_in() ? get_current_user_id() : false;
Shah Alom

2
Để xác thực cookie: Đối với các nhà phát triển thực hiện các yêu cầu Ajax thủ công, nonce sẽ cần phải được thông qua với mỗi yêu cầu. API sử dụng nonces với hành động được đặt thành wp_rest. Những thứ này sau đó có thể được chuyển đến API thông qua tham số dữ liệu _wpnonce (dữ liệu POST hoặc trong truy vấn cho các yêu cầu GET) hoặc thông qua tiêu đề X-WP-Nonce. Nếu không có thông tin nào được cung cấp, API sẽ đặt người dùng hiện tại thành 0, biến yêu cầu thành yêu cầu chưa được xác thực, ngay cả khi bạn đã đăng nhập vào WordPress.
YAMamato

1
Ngay cả với xác thực JWT, bạn vẫn cần phải vượt qua tiêu đề X-WP-Nonce để có được người dùng hiện tại, ví dụ nếu bạn cần truy cập người dùng / tôi vẫn trả về 401, tương tự cho người dùng truy vấn theo vai trò, v.v. Các yêu cầu AJAX "không thủ công" là "đặc biệt" chỉ vì ứng dụng khách API chính thức, bao gồm tiêu đề đó, nhưng không có gì khác.
Jesús Franco

2
@ JesúsFranco bạn đã đúng, đối với các yêu cầu phía máy chủ (trường hợp của tôi), mã thông báo sẽ đủ, đối với các cuộc gọi ajax phía máy khách / thủ công, bạn phải bao gồm nonce để tránh CSRF, không cần phải bao gồm mã thông báo vì bạn đã có có một người dùng đã đăng nhập và phía khách hàng được dựa trên cookie
YAMamato

1

Để có một mẫu mã hoạt động đầy đủ ở đây có một plugin mẫu về cách lấy ID người dùng hiện tại qua REST.

my-plugin.php

class MyPlugin {

  public function __construct() {

    add_action('wp_enqueue_scripts', [$this, 'scripts']);
    add_action('rest_api_init', [$this, 'rest']);
  }

  function scripts() {

    // Add JS.
    wp_enqueue_script('my-plugin', plugin_dir_url(__FILE__) . 'js/scripts.js', ['jquery'], NULL, TRUE);
    // Pass nonce to JS.
    wp_localize_script('my-plugin', 'MyPluginSettings', [
      'nonce' => wp_create_nonce('wp_rest'),
    ]);
  }

  function rest() {

    // Register route.
    register_rest_route('my-plugin/v1', '/uid', [
      'methods'  => WP_REST_Server::READABLE,
      'callback' => [$this, 'rest_callback'],
    ]);
  }

  function rest_callback($data) {

    // Get current user ID.
    $data = [
      'uid' => get_current_user_id(),
    ];

    $response = new WP_REST_Response($data, 200);
    // Set headers.
    $response->set_headers(['Cache-Control' => 'must-revalidate, no-cache, no-store, private']);

    return $response;
  }

}

new MyPlugin();

js / scripts.js

(function($) {

  $(document).ready(function() {

    var settings = MyPluginSettings;

    $.ajax({
      url: '/wp-json/my-plugin/v1/uid',
      method: 'GET',
      beforeSend: function(xhr) {
        xhr.setRequestHeader('X-WP-Nonce', settings.nonce);
      }
    }).done(function(response) {

      // Will return your UID.
      console.log(response);
    });

  });

})(jQuery);

Tài nguyên: https://developer.wordpress.org/rest-api/USE-the-rest-api/authentication/


Tôi không hiểu làm thế nào 'MyPluginSinstall' được chuyển sang tập lệnh. Những điều có thể xem xét: Tôi hiện không sử dụng JQuery nhưng "vanilla" JavaScript ... Tôi đã sử dụng tập lệnh của mình trong các thẻ html <script> khi cần, nhưng tôi đã thử bao gồm chúng với wp_enqueue_script và gặp vấn đề tương tự.
TTT

1
Tôi đã làm việc này, tôi đã viết một số đường dẫn sai khi điều chỉnh cho wp_enqueue_script (). Nhưng ngoài ra, tôi có nhiều tập lệnh và tôi chỉ hiểu rằng tham số đầu tiên của wp_enqueue_script () không thực sự cụ thể đối với trình cắm mà chỉ dành riêng cho tập lệnh (có lẽ bạn nên thay đổi 'plugin của tôi' trong câu trả lời vì điều đó gây nhầm lẫn .
TTT

@TTT - Hoán đổi nó my-scriptchẳng hạn? Có, nó chỉ nên là một số tên xử lý duy nhất, thường chứa tên của plugin hoặc chủ đề.
leymannx

1

wp_get_current_user()không hoạt động vì người dùng của bạn không được thiết lập hoàn hảo. Xem mã dưới đây /wp-includes/user.phpđể tham khảo.

if ( ! empty( $current_user ) ) {
    if ( $current_user instanceof WP_User ) {
        return $current_user;
    }

    // Upgrade stdClass to WP_User
    if ( is_object( $current_user ) && isset( $current_user->ID ) ) {
        $cur_id       = $current_user->ID;
        $current_user = null;
        wp_set_current_user( $cur_id );
        return $current_user;
    }

    // $current_user has a junk value. Force to WP_User with ID 0.
    $current_user = null;
    wp_set_current_user( 0 );
    return $current_user;
}

if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
    wp_set_current_user( 0 );
    return $current_user;
}

Tất cả những gì bạn cần làm là wp_set_cản_user ({user_id}) khi bắt đầu API của bạn.


0

Nếu một lệnh gọi API xuất hiện mà không có tập hợp nonce, WordPress sẽ xác thực lại yêu cầu, giết chết người dùng hiện tại và làm cho yêu cầu không được xác thực. Bảo vệ CSFR này là tự động và bạn không phải làm bất cứ điều gì để nó hoạt động ngoài việc bao gồm cả nonce.

Cách để giải quyết điều này là bao gồm một nonce. Một cái gì đó như thế này:

$_wpnonce = wp_create_nonce( 'wp_rest' );
echo "<input type = 'hidden' name = '_wpnonce' value = '$_wpnonce' />";

Và bao gồm nó trong yêu cầu API của bạn. Nonce phải được gọi là "_wpnonce" và hành động phải là "wp_rest" để API hoạt động. Nó có thể đi trong URL hoặc trong cơ thể bài.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.