WordPress REST API — разрешить всем публиковать сообщения

Я создаю приложение на WordPress, для которого требуется простая форма переднего плана, где любой может отправить информацию, которую необходимо сохранить в базе данных. Я пытаюсь справиться с этим через REST API. (Из-за характера приложения не может быть перенаправления страницы при отправке этой информации.)

У меня нет проблем с настройкой REST API (v2), чтобы я мог отправить сообщение. Он отлично работает, когда я вхожу в WordPress. Когда я пытаюсь заполнить форму, не авторизовавшись в WordPress, я получаю сообщение об ошибке.

Не удалось загрузить ресурс: сервер ответил со статусом 403 (Запрещено)

Как я могу настроить API для получения POST от кого-либо без аутентификации?

Вот мой javascript:

$( '#post-submission-form' ).on( 'submit', function(e) {
    e.preventDefault();
    var title = $( '#post-submission-title' ).val();
    var excerpt = $( '#post-submission-excerpt' ).val();
    var content = $( '#post-submission-content' ).val();
    var status = 'draft';

    var data = {
        title: title,
        excerpt: excerpt,
        content: content
    };

    $.ajax({
        method: "POST",
        url: POST_SUBMITTER.root + 'wp/v2/posts',
        data: data,
        beforeSend: function ( xhr ) {
            //xhr.setRequestHeader( 'X-WP-Nonce', POST_SUBMITTER.nonce );
        },
        success : function( response ) {
            console.log( response );
            alert( POST_SUBMITTER.success );
        },
        fail : function( response ) {
            console.log( response );
            alert( POST_SUBMITTER.failure );
        }

    });

});

Вот как я инициализирую свой javascript:

function holiday_scripts() {

    // Onload JS
    wp_enqueue_script( 'holiday-js', get_template_directory_uri() . '/js/holiday.js', array(), false, true );

    //localize data for script
    wp_localize_script( 'holiday-js', 'POST_SUBMITTER', array(
        'root' => esc_url_raw( rest_url() ),
        'nonce' => wp_create_nonce( 'wp_rest' ),
        'success' => __( 'Thanks for your submission!', 'your-text-domain' ),
        'failure' => __( 'Your submission could not be processed.', 'your-text-domain' ),
        'current_user_id' => 9
        )
     );
}
add_action( 'wp_enqueue_scripts', 'holiday_scripts' );

Кто-нибудь знает, как это сделать?

Спасибо!


person Marc    schedule 16.11.2015    source источник


Ответы (1)


Существует три разных варианта аутентификации в REST API:

  1. Cookie - это то, что вы используете сейчас
  2. OAuth — требуется подключаемый модуль OAuth и ключ для внедрения на интерфейсе.
  3. Basic - требует встраивания имени пользователя/пароля в интерфейс

См. документацию по использованию этих методов здесь: http://v2.wp-api.org/guide/authentication/.

Существуют очевидные риски безопасности при встраивании информации для аутентификации во внешний интерфейс, которая требуется для OAuth и Basic, так как любой сможет аутентифицироваться как пользователь, с которым связан ключ. Я недостаточно знаком с плагином WP OAuth, чтобы знать, насколько детально вы можете контролировать доступ, но я не думаю, что вы действительно можете это сделать.

Самое простое решение — написать собственный метод вне REST API для обработки этих обновлений (или внести свой вклад в проект, чтобы сделать возможными неаутентифицированные запросы). Я написал руководство по созданию функций AJAX на своем веб-сайт, но в основном вы хотите прикрепить функцию к хуку wp_ajax_nopriv_*, где * — это параметр действия вашего запроса. В вашей подключенной PHP-функции вы обрабатываете вставку сообщения и отвечаете с помощью JSON (вы даже можете соответствовать формату WP REST API).

PHP

// insert new post
function create_post_33741541() {
    // use the $_POST to create your post
    $args = array(
         'post_title' => isset( $_POST['title'] )? $_POST['title'] : 'Empty Title',
         // more parameters....
    );
    $post_id = wp_insert_post( $args );

    // make a response
    $response = array( 'post_id' => $post_id, 'message' => 'post created!' );

    // set the content type and return json encode response, then exit
    header( 'Content-type: application/json' );
    die( json_encode( $response ) );
}
// use wp_ajax_nopriv to access from front end
add_action( 'wp_ajax_nopriv_create_post_33741541', 'create_post_33741541' );
add_action( 'wp_ajax_create_post_33741541', 'create_post_33741541' );

JavaScript

function createThePost(){
    var data = {
        // use the part after "wp_ajax_nopriv" as the action
        action: 'create_post_33741541',
        title: 'Your title',
        // other params
    };

    $.ajax({
        method: "POST",
        url: ajaxurl,
        data: data,
        // your handlers
    });
}
person doublesharp    schedule 16.11.2015
comment
Спасибо за ответ. Я тестирую этот маршрут, но не могу заставить PHP-часть этого сработать. Я добавил аналогичную версию вашей функции в свой functions.php, но, похоже, мои значения не передаются. Как анализируются «данные» в функции PHP? Похоже, что $args в том виде, в каком он передается в wp_insert_post($args), не является этими данными. - person Marc; 16.11.2015
comment
Код в моем ответе не будет работать, только псевдокод. Данные отправляются как POST, поэтому, если вы хотите получить action, вы должны использовать $_POST['action']. $args для вставки должно содержать некоторые обязательные значения, ознакомьтесь с документацией для этого метода. - person doublesharp; 16.11.2015
comment
Для совершенно другого варианта вы также можете попробовать это: advancedcustomfields.com/resources/ - person doublesharp; 16.11.2015
comment
Весь смысл всего этого в том, чтобы отправить данные, не вызывая обновления страницы. ...Что нужно указать в URL-адресе ajax для WordPress? - person Marc; 16.11.2015
comment
Ах, тогда ACF не будет работать. ajaxurl, скорее всего, уже установлен WordPress, но если нет, вы можете использовать wp-load.php или /wp-admin/admin-ajax.php (последнее используется WordPress). - person doublesharp; 16.11.2015
comment
Также имейте в виду, что is_admin() вернет true для запроса AJAX, идущего к /wp-admin/admin-ajax.php, даже если пользователь не вошел в систему. - person doublesharp; 16.11.2015
comment
Могу ли я использовать /wp-admin/admin-ajax.php в качестве действия, только если я вошел в систему? Теперь отправка работает отлично, пока я не выйду из WordPress, она больше не работает. - person Marc; 16.11.2015
comment
вы должны иметь доступ к этому каталогу, если вы вышли из системы, если только у вас не настроены какие-либо другие средства безопасности. В качестве альтернативы вы можете использовать /wp-load.php вместо ajaxurl. - person doublesharp; 16.11.2015
comment
Ага! Я понял. В wp_ajax_no_priv нет _. Создание этого wp_ajax_nopriv решило мои проблемы с выходом из системы. Спасибо! - person Marc; 16.11.2015
comment
Ой, простите... это опечатка. - person doublesharp; 17.11.2015