web-dev-qa-db-fra.com

Pourquoi une différence étrange entre get_current_user_id () lorsque vous utilisez AJAX par rapport à la sortie de document.cookie?

Je développe une fonction Ajax simple dans le cadre d'un plug-in destiné à être utilisé à partir du tableau de bord traditionnel WP Admin, mais je constate une anomalie concernant l'état du cookie de connexion.

Le problème, TL; version DR

La sortie de mes appels Ajax s'exécute toujours dans le contexte d'un utilisateur déconnecté. Plus précisément, get_current_user_id() renvoie 0 pour tous les appels lancés par Ajax, malgré le var_dump(get_current_user_id()) côté PHP renvoyant le numéro d'identification correct de l'utilisateur connecté à la sortie de la page elle-même.

Le contrôle de document.cookie semble confirmer l’absence de cookie de connexion du côté JS, mais un var_dump($_COOKIE) indique la présence du cookie de connexion correct.

Pour ajouter à l'étrangeté, la sous-fenêtre Réseau de Firefox affiche le cookie complet, ainsi que la valeur de connexion, envoyé à WordPress à partir de l'appel Ajax.

Ce qui donne?

Code et contexte

Lorsqu'un certain WP admin tableau de bord est chargé, mon JS interroge simplement WP-API (v2) pour obtenir des commentaires sur un message donné. La méthode de sondage ressemble à ceci:

/**
 * Checks for any new comments.
 */
var pollForNewComments = function () {
    var url = api_base + '/comments&post=' + getPostId() + '&offset=' + getCommentCount();
    console.log(document.cookie);
    jQuery.get(url, function (response) {
        if (response.length) {
            appendComments(response);
            showNewCommentsNotice();
        }
    });
};

Notez l'appel à console.log(document.cookie). Lorsque cette méthode est exécutée, la sortie du journal de la console affiche cette sortie:

wordpress_test_cookie=WP+Cookie+check; wp-settings-time-10=1456479389; popunder=yes; popundr=yes; setover18=1

Notez qu'il n'y a pas de cookie de connexion.

Cependant, pour le même appel , le volet réseau de Firefox indique que le cookie de connexion existe-t-il dans les en-têtes de la requête HTTP:

Firefox Network Panel screenshot shows login cookie, even though earlier console.log() call does not???

Pour vérifier que le cookie de connexion est bien reçu par WordPress, j'exécute une var_dump(get_current_user_id()); var_dump($_COOKIE); exit(); triviale dans mon code de plugin, et le résultat de l'appel Ajax confirme que, malgré la présence du cookie de connexion, WordPress pense qu'il n'y a pas d'utilisateur connecté:

int(0)
array(3) {
  ["wordpress_test_cookie"]=>
  string(15) "WP Cookie check"
  ["wordpress_logged_in_9416a7b43bd88dae58cf6c88b9f89f3f"]=>
  string(130) "athirduser|1456650402|a23GIhs43jJ651dKkCEKfX6EKjfnTCpT76k6Hgvznls|5da91c9c365cf214c486b0a32333a78fb6394385e5bcad619666511330322bda"
  ["wp-settings-time-10"]=>
  string(10) "1456479389"
}

La sortie des appels non-Ajax est renvoyée correctement, indiquant qu'un cookie de connexion est présent et que l'ID utilisateur correct est renvoyé.

Pourquoi la différence entre les appels Ajax et non-Ajax ici? Pourquoi la différence entre console.log(document.cookie) et ce que Firefox affiche dans son inspecteur de réseau?

Il s'agit d'une configuration à serveur unique, d'un environnement de développement local, et non d'une requête interdomaine.

Merci.

1
Meitar

Je devais suivre à travers le noyau de WordPress et le code de plug-in d'API REST pour résoudre ce problème, mais je l'ai finalement fait. La solution est décrite ici .

Le TL; DR de la solution est que l’API-WP ignorera le contenu du cookie de connexion et supposera une demande non authentifiée (déconnectée) à moins que la valeur correcte ne soit donnée dans le paramètre _wpnonce HTTP GET (dans la chaîne de requête) ou HTTP_X_WP_NONCE en-tête HTTP. Mon JavaScript n'a pas correctement inclus cela. La méthode JavaScript corrigée ressemble à ceci:

/**     
 * Checks for any new comments.
 */     
var pollForNewComments = function () {
    var url = api_base + '/comments&post=' + getPostId() + '&offset=' + getCommentCount()
        + '&_wpnonce=' + wpApiSettings.nonce;
    jQuery.get(url, function (response) {
        if (response.length) {
            appendComments(response);
            showNewCommentsNotice();
        }
    });
};

Notez que l'ajout du paramètre _wpnonce dans la chaîne de requête avec la variable JavaScript globale wpApiSettings.nonce (ajoutée par le plug-in API REST) résout le problème pour moi.

1
Meitar