web-dev-qa-db-fra.com

Commentaire REST L'authentification par cookie API fonctionne dans WP 4,7?

Bien que je me sois connecté, je ne peux pas créer de publication sur le front-end. WordPress retourne toujours 401 Unauthorized response. J'ai vidé $_COOKIE pour m'assurer que le cookie de connexion a été défini et a obtenu quelque chose comme ceci:

array(1) {
  ["wordpress_logged_in_48f880f2beac6f39fb9ea8d9367e86d6"]=>
  string(125) "admin|1495526369|PwQIf1tAM5khs2f6LKMgf0T7fP1RwHjl9T6OWW90QfD|6d3373f1a05f2fcbfccc429035b0519a012d3224f725b82d6f253a98862b072d"
}

J'ai lu l'intégralité du REST API Handbook et de nombreux tuts:

Lorsque vous vous connectez à votre tableau de bord, les cookies sont correctement configurés. Les développeurs de plug-ins et de thèmes n'ont besoin que d'un utilisateur connecté.

mais je ne peux pas le faire fonctionner. Est-ce que je manque quelque chose ou cela ne fonctionne que sur le tableau de bord d'administration?

Voici mon code source:

// Localized data
/* <![CDATA[ */
var appData = {"routes":{"restUrl":"\/wp-json\/wp\/v2"}};
/* ]]> */

// Post model
App.Model.Post = Backbone.Model.extend({
  urlRoot: appData.routes.restUrl + '/posts'
}

// Init
$(document).ready(function() {
  var post = new App.Model.Post({
    title: 'Posted via REST API',
    content: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
  });
  var xhr = post.save(null, {
    success: function(model, response, options) {
      console.log(response);
    },
    error: function(model, response, options) {
      console.log(response);
    }
  });
});
4
MinhTri

Il semble que vous manquiez la partie nonce , comme expliqué dans le chapitre Authentication , dans le REST Manuel de l'API:

L'authentification par cookie est la méthode d'authentification de base incluse dans WordPress. Lorsque vous vous connectez à votre tableau de bord, les cookies sont correctement configurés. Les développeurs de plug-ins et de thèmes n'ont donc besoin que d'un utilisateur connecté.

Cependant, l'API REST inclut une technique appelée nonces pour éviter les problèmes CSRF. Cela empêche les autres sites de vous forcer à effectuer des actions sans le vouloir explicitement. Cela nécessite un traitement légèrement spécial pour l'API.

Pour les développeurs utilisant l'API Javascript intégrée, cela est géré automatiquement pour vous. C'est le moyen recommandé d'utiliser l'API pour les plugins et les thèmes. Les modèles de données personnalisés peuvent étendre wp.api.models.Base pour s’assurer qu’il est envoyé correctement pour les demandes personnalisées.

Pour les développeurs qui effectuent des requêtes Ajax manuelles, le nonce devra être passé avec chaque requête. L'API utilise des ressources avec l'action définie sur wp_rest. Celles-ci peuvent ensuite être transmises à l'API via le paramètre de données _wpnonce (soit POST data ou dans la requête pour les demandes GET), ou via l'en-tête X-WP-Nonce.

Sur la base du chapitre Client JavaScript Backbone , nous pouvons utiliser la bibliothèque de clients principale wp-api REST API Backbone.

Voici votre extrait modifié dans un fichier de script /js/test.js dans le répertoire du thème actuel:

wp.api.loadPromise.done( function() {

  // Create a new post
  var post = new wp.api.models.Post(
      {
        title: 'Posted via REST API',
        content: 'Lorem Ipsum ... ',
        status: 'draft',  // 'draft' is default, 'publish' to publish it
    }
  );

  var xhr = post.save( null, {
     success: function(model, response, options) {
       console.log(response);
     },
     error: function(model, response, options) {
       console.log(response);
     }
   });

});

où nous avons mis en file d'attente la bibliothèque cliente wp-api et notre script de test avec:

add_action( 'wp_enqueue_scripts', function()
{
    wp_enqueue_script( 'wp-api' );
    wp_enqueue_script( 'test_script', get_theme_file_uri( '/js/test.js' ), [ 'wp-api' ] );

} );

dans le fichier functions.php du thème actuel.

Notez que ce script de test crée simplement un nouveau brouillon, lors de chaque chargement de page sur le serveur frontal, destiné à un utilisateur connecté disposant de la possibilité de créer de nouveaux messages.

4
birgire

Vous n'avez pas besoin de pour vous connecter à votre tableau de bord WordPress avant de consommer l'API WordPress REST à partir d'une application externe; cela n'a pas d'importance (à moins bien sûr que vous souhaitiez vous fier aux cookies au fur et à mesure de votre développement).

Il est important de noter que le partage de ressources inter-origines (CORS) peut déjà être activé côté serveur, sauf si vous utilisez la même origine ou le même serveur.

L'en-tête de réponse HTTP 401 que vous aviez indique qu'une demande non autorisée a été envoyée pour traitement et que votre réponse aurait probablement été:

{
  "code": "rest_cannot_edit",
  "message": "Sorry, you are not allowed to edit this post.",
  "data": {
    "status": 401
  }
}

En d’autres termes, vous êtes soit non connecté dans l’application dont vous demandez l’origine ou bien l’utilisateur exécutant l’action ne dispose pas de l’autorisation requise pour effectuer cette opération .

Supposons qu'il s'agisse du premier cas (un utilisateur non authentifié qui, dans des circonstances normales, dispose de tous les droits pour effectuer l'action envisagée);

La solution évidente a trait à authentifier l'utilisateur avant d'exécuter l'opération _ comme vous l'avez deviné.

La question qui se pose maintenant est la suivante: comment authentifier un utilisateur WordPress via son API REST intégrée?

La bonne nouvelle est que vous avez le choix parmi une gamme d’options en fonction de vos besoins et de vos préférences.

L'extrait ci-dessous montre comment procéder lorsque vous utilisez Backbone.js:

wp.api.loadPromise.done(function() {
  // Create a new post
  var post = new wp.api.models.Post({
    title: 'Posted via REST API',
    content: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
  });
  post.save(null, {
    success: function(model, response, options) {
      console.log(response);
    },
    error: function(model, response, options) {
      console.log(response);
    }
  });
});

N'oubliez pas de mettre en file d'attente wp-api dans votre functions.php ou plugin comme ci-dessous:

/**
 * Either of the two can be used to enqueues in-built WP-API;
 * not both as any of them enables you achieve the same result: to enqueue wp-api.
 * The only difference between them is that one does it independently without any condition
 * while the other does so with a condition: to enqueue it as a dependency for your script.
 */
function wp_api() {
    // Use the line below to enqueue directly
    // (should your code directly reside in your functions.php or plugin).
    wp_enqueue_script( 'wp-api' );

    // Use this option instead if you want to enqueue it (wp-api)
    // as a dependency for your script (here, located in a js file) so as
    // to ensure that your script gets loaded only after wp-api does as it depends on it.
    wp_enqueue_script( 'my_script', 'path/to/my/script', array( 'wp-api' ) );
}
add_action( 'init', 'wp_api' );

... plus de détails sur l'utilisation du client JavaScript Backbone avec WordPress REST API ici .

1
nyedidikeke