Comment utiliser l'authentification OAuth avec l'API REST via les commandes CURL?


18

J'essaie d'utiliser WordPress Rest Api avec authentification pour obtenir plus de données de l'API. J'ai installé le plugin Oauth, le plugin rest-api et obtenu les informations d'identification de l'API de WP-CLI.

J'ai compris comment accéder aux données sans autorisation. Cela marche:

// set our end point
$domain = "http://localhost/wp-api";
$endpoint = $domain."/wp-json/wp/v2/posts/";


$curl = curl_init($endpoint);

curl_setopt_array($curl, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_URL            => $endpoint,
]);
$response = curl_exec($curl);
$decoderesponse = json_decode($response, true);

?>

<pre>
  <?php print_r($decoderesponse); ?>
</pre>

Mais je ne peux pas comprendre comment m'authentifier avec des informations d'identification. Voici ma tentative. Je ne sais pas si "clé" et "secret" sont corrects.

// Oauth credentials from wp-cli
$ID = "4";
$Key = "l8XZD9lX89kb";
$Secret = "UUbcc8vjUkGjuDyvK1gRTts9sZp2N8k9tbIQaGjZ6SNOyR4d";

// set our end point
$domain = "http://localhost/wp-api";
$endpoint = $domain."/wp-json/wp/v2/posts/1/revisions";

$headers[] = "key=$Key";
$headers[] = "secret=$Secret";

$curl = curl_init($endpoint);

curl_setopt_array($curl, [
  CURLOPT_HTTPHEADER     => $headers,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_URL            => $endpoint,
]);
$response = curl_exec($curl);
$decoderesponse = json_decode($response, true);

?>

<pre>
  <?php print_r($decoderesponse); ?>
</pre>

La sortie est

Array
(
    [code] => rest_cannot_read
    [message] => Sorry, you cannot view revisions of this post.
    [data] => Array
        (
            [status] => 401
        )
)

Comment puis-je faire en sorte que cela fonctionne? Je vous remercie.


2
Les choses ne sont pas si faciles. J'ai essayé d'écrire une réponse mais c'est assez long. Vous pouvez commencer par lire les documents, en particulier le flux d'autorisation . Ce poste a également un excellent tutoriel .
cybmeta

Réponses:


10

Allons étape par étape ici. On dirait que vous essayez d'utiliser OAuth uniquement pour l'authentification, mais avant de pouvoir le faire, vous devez obtenir le jeton d'accès qui sera utilisé pour s'authentifier lorsque vous effectuez vos appels d'API.

Dans la mesure où cela utilise OAuth version 1, pour obtenir le jeton d'accès, vous devez procéder comme suit:

  1. Tout d'abord, configurez une application, appelez le site pour obtenir le jeton de demande (informations d'identification temporaires) à l'aide de l'ID client et du secret de l'application
  2. Ensuite, appelez le site pour autoriser l'application avec le jeton de demande de la première étape (face à l'utilisateur, voir ci-dessous).
  3. Troisièmement, une fois l'autorisation terminée, vous appelez ensuite le site pour obtenir le jeton d'accès (maintenant que l'application a été autorisée)

Je recommande d'utiliser Postman pour les premières étapes, car elles ne doivent être effectuées qu'une seule fois. Postman gérera également la génération de timestamp, nonceet oauth signaturedonc, si vous n'utilisez pas de bibliothèque OAuth, vous devez absolument utiliser Postman. Une fois que vous avez votre jeton d'accès, vous pouvez passer les appels via CURL sans aucune bibliothèque.

https://www.getpostman.com/

Première étape (application de configuration)

Installez le plugin WP OAuth 1, activez, puis passez à l'élément de menu sous Utilisateurs> Applications . Ajoutez une nouvelle application, remplissez le nom et la description. Pour le rappel, soit l'URL vers laquelle rediriger l'utilisateur (après l'autorisation), soit ooppour le flux hors bande qui redirigera vers une page interne qui affiche le jeton de vérification (au lieu de rediriger).

https://github.com/WP-API/OAuth1/blob/master/docs/basics/Registering.md

Pour passer à la deuxième étape, un appel doit être effectué sur votre site, à l'aide de l' ID client et du secret client de l'application créée, pour obtenir des informations d'identification temporaires (jeton de demande).

Ouvrez Postman, créez un nouvel appel http://website.com/oauth1/request, cliquez sur l'onglet Autorisation, sélectionnez OAuth 1.0 dans la liste déroulante, entrez la clé client, le secret client, définissez la méthode de signature sur HMAC-SHA1, activez ajouter des paramètres à l'en-tête, encodez la signature oauth , puis cliquez sur Mettre à jour la demande

Postman OAuth1 Request

Postman générera automatiquement la signature, le nonce et l'horodatage pour vous, et les ajoutera à l'en-tête (vous pouvez voir sous l'onglet En-têtes).

Cliquez sur Envoyer et vous devriez obtenir une réponse qui comprend oauth_tokenet oauth_token_secret: Postman OAuth1 Request Response

Ces valeurs seront utilisées à l'étape suivante pour autoriser l'application sous votre compte utilisateur WordPress.

Deuxième étape (autoriser la demande)

L'étape d'autorisation ne doit être effectuée qu'une seule fois, cette étape est destinée à l'utilisateur et celle que tout le monde connaît. Cette étape est obligatoire car vous utilisez OAuth1 et l'application doit être associée à un compte utilisateur WordPress. Pensez quand un site vous permet de vous connecter avec Facebook ... ils vous dirigent vers Facebook où vous vous connectez et cliquez sur "Autoriser" ... cela doit être fait, simplement via votre site WordPress.

Je recommande d'utiliser votre navigateur Web pour cette étape, car vous pouvez facilement définir les variables dans l'URL, ce qui fournit la page "Autoriser" pour autoriser l'application.

Ouvrez votre navigateur Web et saisissez l'URL de votre site, comme ceci: http://website.com/oauth1/authorize

Maintenant, ajoutez à cette URL, oauth_consumer_key(ID client) oauth_tokenet oauth_token_secret(à partir de l'étape précédente). Dans mon exemple, voici l'URL complète:

http://website.com/oauth1/authorize?oauth_consumer_key=TUPFNj1ZTd8u&oauth_token=J98cN81p01aqSdFd9rjkHZWI&oauth_token_secret=RkrMhw8YzXQljyh99BrNHmP7phryUvZgVObpmJtos3QExG1O

OAuth1 Authorize Application

Une fois que vous cliquez sur Autoriser, vous obtiendrez un autre écran avec le jeton de vérification. Dans mon exemple, c'est le jeton de vérification retournéE0JnxjjYxc32fMr2AF0uWsZm

Troisième étape (obtenir un jeton d'accès)

Maintenant que nous avons autorisé l'application, nous devons effectuer un dernier appel pour obtenir le jeton d'autorisation qui sera utilisé pour effectuer tous vos appels API. Tout comme la première étape, je vais utiliser Postman (car la signature doit être HMAC-SHA1), et il est 100 fois plus facile de terminer ces étapes.

Ouvrez à nouveau Postman et remplacez l'URL par http://website.com/oauth1/access

Assurez-vous d'ajouter le Token et le Token Secret (valeurs de la première étape), puis cliquez sur Paramètres pour afficher les cases sous l'URL. À gauche, tapez oauth_verifier et à droite, entrez le code de la deuxième étape, le jeton de vérification

Étape d'accès à Postman OAuth1

Assurez-vous de cliquer sur Mettre à jour la demande, puis sur Envoyer, et vous devriez obtenir une réponse avec oauth_tokenet oauth_token_secret... c'est ce dont vous avez besoin pour passer vos appels API! Jetez les originaux de l'étape 1, enregistrez-les dans votre code ou ailleurs en toute sécurité.

Réponse de Postman OAuth1 Access

Vous pouvez ensuite effectuer un appel API à votre site, en définissant les en-têtes avec le jeton retourné et le secret du jeton.

Vous pouvez passer de plusieurs façons, via l'en-tête d'autorisation, dans les paramètres GET ou POST (si codé en tant qu'application / x-www-form-urlencoded). N'oubliez pas que vous DEVEZ passer la signature, l'horodatage et le nonce. Je ne savais pas combien de temps cette réponse me prendrait, donc je mettrai à jour cela demain avec un exemple sur la façon de le faire avec votre code.

Je recommande fortement d'installer le journal d'API Rest afin que vous puissiez afficher le journal des appels d'API et voir ce qui a été envoyé, retourné, etc. Cela vous aidera énormément à déboguer.

https://github.com/petenelson/wp-rest-api-log


Je sais, il existe de nombreux didacticiels avec Postman ou des outils similaires, mais je ne trouve aucun didacticiel pour effectuer l'ensemble du processus avec les fonctionnalités CURL, je veux dire du code PHP pur. C'est ce que je veux.
MinhTri

@ Dan9 TBH ce n'est pas vraiment possible ... du moins pas avec OAuth1, principalement parce que vous devez AUTORISER l'application sous un compte utilisateur. Toutes les autres étapes sont faciles à faire avec CURL, le problème est d'utiliser CURL pour vous connecter en tant qu'utilisateur WordPress (ce qui signifie que vous devez stocker les informations d'identification dans votre fichier PHP, ce qui n'est PAS une bonne idée), ET pour autoriser l'application, que vous pourrait modifier la base de code OAuth1, mais honnêtement, si vous voulez utiliser CURL pour TOUT ... vous pensez à cela de la mauvaise façon et devriez trouver une autre solution ou méthode.
sMyles

@ Dan9 avec ce que vous essayez de faire, vous devez utiliser le serveur OAuth2 au lieu d'OAuth1, principalement parce que OAuth2 a de nouvelles fonctionnalités, y compris le type d'octroi d'informations d'identification client, ce qui évite d'avoir à passer par toutes ces étapes bshaffer.github.io / oauth2-server-php-docs / grant-types /…
sMyles

@ Dan9 si vous êtes à 100% prêt à obtenir de l'aide pour le faire via OAuth1, en utilisant CURL, je pense que c'est possible avec quelques hacks de code, mais comme je l'ai mentionné, cela signifie que vous devez enregistrer le NOM D'UTILISATEUR et le MOT DE PASSE d'un utilisateur dans le fichier PHP. Si vous êtes d'accord avec cela, faites-le moi savoir et rédigez un tutoriel pour le faire en utilisant CURL, ne voulez pas passer du temps à écrire un tutoriel si vous allez utiliser OAuth2 ou si vous n'en avez plus besoin
sMyles

@ Dan9 bien ... c'est juste ça ... si vous allez utiliser OAuth1, vous devez associer un compte utilisateur WordPress. Pensez fondamentalement au jeton d'accès comme une clé API ... la "clé API" doit être associée à un compte d'utilisateur ... maintenant, si vous utilisez un compte standard que vous configurez, c'est à vous de décider ... mais peu importe quand vous utilisez OAuth1, il DOIT être associé à un compte d'utilisateur, d'où le long processus d'obtention du jeton d'accès.
sMyles

2

Ajouter ceci comme une autre réponse pour vous aider à comprendre comment procéder. Fondamentalement, comme mentionné dans mes commentaires, si vous allez utiliser OAuth1, vous DEVEZ l'associer à un compte d'utilisateur, pas question.

Vous devez d'abord utiliser CURL pour vous connecter au site avec un mot de passe de nom d'utilisateur pour WordPress, stocker le cookie afin que vous puissiez l'utiliser dans votre appel CURL à OAuth (assurez-vous de mettre à jour votre appel CURL pour inclure le cookie):

/programming/724107/wordpress-autologin-using-curl-or-fsockopen-in-php

Appelez ensuite OAuth à l'aide de CURL avec l'ID client et le secret client, pour obtenir le jeton oauth temporaire et le secret (jeton de demande)

Pour effectuer cet appel (et l'appel pour obtenir un jeton d'accès), vous devez configurer correctement votre appel CURL. Voir la fin de cette réponse pour le code et les références.

Après avoir obtenu le jeton oauth temporaire et le secret (jeton de demande), effectuez un appel CURL POST à ​​cette URL de votre site:

http://website.com/oauth1/authorize

Vous devrez ensuite extraire toutes les valeurs du code HTML renvoyé pour la page d'autorisation, puis soumettre votre propre POST à ​​l'URL de l'action de formulaire.

/programming/35363815/how-to-get-a-value-input-from-html-returned-of-curl

Plus précisément, ceux-ci doivent être inclus dans vos données POST pour terminer le POST "autorisation" à http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Ceci est la valeur nonce pour le formulaire à soumettre, cela DOIT être extrait de l'entrée HTML et soumis avec votre POST

    consumer - Ceci est une entrée cachée dans le HTML (il s'agit d'une référence à un ID de publication, vous devez donc le retirer de l'entrée HTML

    oauth_token - Ceci est une entrée cachée dans le HTML (mais vous devriez aussi déjà l'avoir)

    wp-submit - Cela doit être réglé sur la valeur authorize

Voici un exemple de code HTML généré pour la page d'authentification:

<form name="oauth1_authorize_form" id="oauth1_authorize_form" action="http://website.com/wp-login.php?action=oauth1_authorize" method="post">

    <h2 class="login-title">Connect My Auth</h2>

    <div class="login-info">
        <p>Howdy <strong>admin</strong>,<br/> "My OAuth Demo" would like to connect to Example Site.</p>

    </div>

    <input type="hidden" name="consumer" value="5428" /><input type="hidden" name="oauth_token" value="i1scugFXyPENniCP4kABKtGb" /><input type="hidden" id="_wpnonce" name="_wpnonce" value="ca9b267b4f" /><input type="hidden" name="_wp_http_referer" value="/wp-login.php?action=oauth1_authorize&amp;oauth_consumer_key=TUPFNj1ZTd8u&amp;oauth_token=i1scugFXyPENniCP4kABKtGb&amp;oauth_token_secret=gzqW47pHG0tilFm9WT7lUgLoqN2YqS6tFFjUEiQoMgcmG2ic" />   <p class="submit">
        <button type="submit" name="wp-submit" value="authorize" class="button button-primary button-large">Authorize</button>
        <button type="submit" name="wp-submit" value="cancel" class="button button-large">Cancel</button>
    </p>

</form>

Après avoir effectué le POST avec toutes ces valeurs / données, c'est le code HTML qui sera renvoyé avec le code d'autorisation (vous devez donc extraire la valeur de l'intérieur du <code>bloc:

<div id="login">
    <h1><a href="https://wordpress.org/" title="Powered by WordPress" tabindex="-1">Example Site</a></h1>
    <p>Your verification token is <code>yGOYFpyawe8iZmmcizqVIw3f</code></p> <p id="backtoblog"><a href="http://website.com/">&larr; Back to Example Site</a></p>
</div>

Une fois que vous avez le jeton de vérification, vous pouvez ensuite appeler /oauth1/accessle jeton de vérification, le jeton oauth et le secret du jeton oauth. Le jeton de vérification doit être placé dans les données POST en tant queoauth_verifier

Cela rendra votre nouveau jeton d'accès permanent et VOILA!

Exemple de code CURL

Voici un exemple de code pour effectuer l'appel CURL, la partie la plus importante étant la façon dont le oauth_signatureest généré:

https://oauth1.wp-api.org/docs/basics/Signing.html

function buildBaseString($baseURI, $method, $params){
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }

    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth){
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";

    $r .= implode(', ', $values);
    return $r;
}

// Add request, authorize, etc to end of URL based on what call you're making
$url = "http://domain.com/oauth/";

$consumer_key = "CLIENT ID HERE";
$consumer_secret = "CLIENT SECRET HERE";

$oauth = array( 'oauth_consumer_key' => $consumer_key,
                'oauth_nonce' => time(),
                'oauth_signature_method' => 'HMAC-SHA1',
                'oauth_callback' => 'oob',
                'oauth_timestamp' => time(),
                'oauth_version' => '1.0');

$base_info = buildBaseString($url, 'GET', $oauth);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;


$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$return_data = json_decode($json);

print_r($return_data);

Ce site explique exactement comment encoder la signature OAuth et comment envoyer en utilisant CURL (je recommande de lire la page entière): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- Les données/

Plus de ressources sur la génération de signature OAuth1: /programming/24613277/oauth-signature-generation-using-hmac-sha1

Autres ressources: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/


Comment puis-je obtenir l'ID client et le secret client et les associer à un utilisateur valide? Actuellement, seuls les administrateurs peuvent créer une nouvelle application et cela se produit uniquement via le tableau de bord administrateur. Btw, j'ai essayé de générer oauth_signaturecomme vous l'avez dit mais, en quelque sorte, la réponse est toujours json_oauth1_signature_mismatch.
MinhTri

@ Dan9 oui c'est correct, les administrateurs doivent créer l'application, sinon ce serait un énorme problème de sécurité permettant aux applications d'être créées par des utilisateurs anonymes. Voici quelques sites concernant la signature wordpress.stackexchange.com/questions/185511/… github.com/WP-API/OAuth1/issues/34 github.com/WP-API/OAuth1/issues/27
sMyles

0

Mise à jour: D'après ce que j'ai lu, vous devez faire plusieurs boucles pour obtenir le access_token, que vous utilisez ensuite pour faire la requête

  • Acquisition des informations d'identification temporaires: le client obtient un ensemble d'informations d'identification temporaires du serveur.
  • Autorisation: L'utilisateur "autorise" le jeton de demande pour accéder à son compte.
  • Échange de jeton: le client échange les informations d'identification temporaires de courte durée contre un jeton de longue durée.

flux de serveur oauth1


0

Je sais que j'arrive un peu tard, mais pouvez-vous utiliser wp_remote_get et _post?

Je tire et publie du contenu avec mon installation wordpress en les utilisant:

C'est l'idée générale du codex wordpress:

$response = wp_remote_post( $url, array(
    'body'    => $data,
    'httpversion' => '1.0',
    'sslverify' => false,
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ),
    ),
) );

Voici un exemple plus spécifique:

$url='http://WWW.EXAMPLE HERE.';
$response = wp_remote_post( $url, array(
    'method' => 'POST',
    'timeout' => 45,
    'redirection' => 5,
    'httpversion' => '1.0', //needed to get a response
    'blocking' => true,
    'headers' => array('Authorization' => 'Basic ' . base64_encode( 'MY TOKENID' . ':' . '' )),
    'body' => $body // in array
    'cookies' => array()
    )
);

if ( is_wp_error( $response ) ) {
   $error_message = $response->get_error_message();
   echo "Something went wrong: $error_message";
} else {
 //  echo 'Response:<pre>';
 //  print_r( $response );
 //    echo '</pre>'; 
$responseBody = json_decode($response['body'],true);
echo $responseBody['message'];

    }
    }
}

L'astuce consiste à encoder le nom d'utilisateur et pw. Maintenant, le temps dépend souvent du nom d'utilisateur de l'API et pw sera soit vide, soit vos jetons.

Ainsi, par exemple dans mon exemple spécifique ci-dessus, les en-têtes étaient

'headers' => array('Authorization' => 'Basic ' . base64_encode( 'MYTOKENID' . ':' . '' ))

et j'ai laissé pw vide. Cela dépend du système d'API que vous utilisez.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.