Come utilizzare l'autenticazione OAuth con le API REST tramite comandi CURL?
Sto cercando di utilizzare la WordPress REST API con autenticazione per ottenere più dati dall'API. Ho installato il plugin OAuth, il plugin rest-api e ho ottenuto le credenziali API da WP-CLI.
Ho capito come accedere ai dati senza autorizzazione. Questo funziona:
// imposta il nostro endpoint
$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>
Ma non riesco a capire come autenticarmi con le credenziali. Questo è il mio tentativo. Non sono sicuro se "key" e "secret" siano corretti.
// Credenziali OAuth da wp-cli
$ID = "4";
$Key = "l8XZD9lX89kb";
$Secret = "UUbcc8vjUkGjuDyvK1gRTts9sZp2N8k9tbIQaGjZ6SNOyR4d";
// imposta il nostro endpoint
$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>
L'output è
Array
(
[code] => rest_cannot_read
[message] => Spiacenti, non puoi visualizzare le revisioni di questo post.
[data] => Array
(
[status] => 401
)
)
Come posso farlo funzionare? Grazie.

Procediamo passo dopo passo qui. Sembra che tu stia cercando di utilizzare OAuth solo per l'autenticazione, ma prima di poterlo fare è necessario ottenere il Token di Accesso che verrà utilizzato per autenticarti quando effettuerai le chiamate API.
Poiché si utilizza OAuth versione 1, per ottenere il Token di Accesso devi seguire questi passaggi:
- Primo, configura un'applicazione, effettua una chiamata al sito per ottenere il Token di Richiesta (credenziali temporanee) utilizzando l'ID Client e il Secret dell'applicazione
- Secondo, effettua una chiamata al sito per Autorizzare l'applicazione con il Token di Richiesta ottenuto nel primo passaggio (interfaccia utente, vedi sotto).
- Terzo, dopo che l'autorizzazione è stata completata, effettua una chiamata al sito per ottenere il Token di Accesso (ora che l'applicazione è stata autorizzata)
Consiglio di utilizzare Postman per i primi passaggi, poiché devono essere completati solo una volta. Postman gestirà anche la generazione del timestamp
, nonce
e oauth signature
, quindi se non stai utilizzando una libreria OAuth, dovresti assolutamente usare Postman. Una volta ottenuto il Token di Accesso puoi effettuare le chiamate via CURL senza alcuna libreria.
Primo Passo (configurazione applicazione)
Installa il plugin WP OAuth 1, attivalo, poi vai alla voce di menu Utenti > Applicazioni. Aggiungi una nuova applicazione, compila nome e descrizione. Per il callback inserisci l'URL a cui reindirizzare l'utente (dopo l'autorizzazione), oppure oop
per il flusso Out-of-Band che reindirizzerà a una pagina interna che mostra il token di verifica (invece di reindirizzare).
https://github.com/WP-API/OAuth1/blob/master/docs/basics/Registering.md
Per procedere al secondo passaggio, è necessario effettuare una chiamata al tuo sito, utilizzando l'ID Client e il Secret Client dell'applicazione creata, per ottenere le credenziali temporanee (Token di Richiesta).
Apri Postman, crea una nuova chiamata a http://website.com/oauth1/request
, clicca sulla scheda Autorizzazione, seleziona OAuth 1.0 dal menu a discesa, inserisci la Client Key, Client Secret, imposta il metodo di firma su HMAC-SHA1
, abilita l'aggiunta dei parametri all'header, codifica la firma oauth, poi clicca su Aggiorna Richiesta
Postman genererà automaticamente la firma, il nonce e il timestamp per te, e li aggiungerà all'header (puoi visualizzarli sotto la scheda Headers).
Clicca Invia e dovresti ottenere una risposta che include oauth_token
e oauth_token_secret
:
Questi valori verranno utilizzati nel prossimo passaggio per autorizzare l'applicazione sotto il tuo account utente WordPress.
Secondo Passo (autorizzazione applicazione)
Il passaggio di autorizzazione deve essere completato solo una volta, questo passaggio è rivolto all'utente, ed è quello che tutti conoscono. Questo passaggio è obbligatorio perché stai utilizzando OAuth1, e l'applicazione deve essere associata a un account utente WordPress. Pensa a quando un sito ti permette di accedere con Facebook... ti reindirizzano a Facebook dove effettui il login e clicchi "Autorizza"... questo deve essere fatto, ma attraverso il tuo sito WordPress.
Consiglio di utilizzare il tuo browser web per questo passaggio, poiché puoi facilmente impostare le variabili nell'URL, e questo mostra la pagina "Autorizza" per autorizzare l'applicazione.
Apri il tuo browser web e digita l'URL del tuo sito, in questo modo:
http://website.com/oauth1/authorize
Ora aggiungi a questo URL, oauth_consumer_key
(ID Client), oauth_token
e oauth_token_secret
(dal passaggio precedente). Nel mio esempio questo è l'URL completo:
http://website.com/oauth1/authorize?oauth_consumer_key=TUPFNj1ZTd8u&oauth_token=J98cN81p01aqSdFd9rjkHZWI&oauth_token_secret=RkrMhw8YzXQljyh99BrNHmP7phryUvZgVObpmJtos3QExG1O
Una volta cliccato su Autorizza, otterrai un'altra schermata con il token di verifica. Nel mio esempio questo è il token di verifica restituito E0JnxjjYxc32fMr2AF0uWsZm
Terzo Passo (ottenere token di accesso)
Ora che abbiamo autorizzato l'applicazione, dobbiamo effettuare un'ultima chiamata per ottenere il Token di Autorizzazione che verrà utilizzato per effettuare tutte le tue chiamate API. Come nel primo passaggio utilizzerò Postman (perché la firma deve essere HMAC-SHA1), e rende questi passaggi 100 volte più semplici da completare.
Apri nuovamente Postman e cambia l'URL in http://website.com/oauth1/access
Assicurati di aggiungere il Token e il Token Secret (valori ottenuti nel primo passaggio), poi clicca su Params per mostrare le caselle sotto l'URL. A sinistra digita oauth_verifier e a destra inserisci il codice ottenuto nel secondo passaggio, il Token di Verifica
Assicurati di cliccare su Aggiorna Richiesta, poi clicca su Invia, e dovresti ottenere una risposta con oauth_token
e oauth_token_secret
... questo è ciò che ti serve per effettuare le tue chiamate API! Scarta quelli originali ottenuti nel passaggio 1, salva questi nel tuo codice o in un posto sicuro.
Puoi quindi effettuare una chiamata API al tuo sito, impostando gli header con il token e il token secret restituiti.
Puoi passarli in diversi modi, tramite header di Autorizzazione, nei parametri GET, o POST (se codificato come application/x-www-form-urlencoded). Tieni presente che DEVI passare la firma, il timestamp e il nonce. Non mi ero reso conto di quanto tempo mi avrebbe richiesto questa risposta, quindi aggiornerò domani con un esempio su come farlo con il tuo codice.
Consiglio vivamente di installare Rest API log per poter visualizzare il log delle chiamate API, e vedere cosa è stato inviato, restituito, ecc. Questo aiuterà tantissimo nel debug.

Lo so, ci sono molti tutorial con Postman o strumenti simili ma non riesco a trovare tutorial che mostrino l'intero processo con le funzionalità CURL, intendo codice PHP puro. Questo è quello che voglio.

@Dan9 Ad essere sinceri non è davvero possibile... almeno non con OAuth1, principalmente perché devi AUTORIZZARE l'applicazione sotto un account utente. Tutti gli altri passaggi sono facili da fare con CURL, il problema è usare CURL per accedere come utente WordPress (il che significa che devi memorizzare le credenziali nel tuo file PHP e NON è una buona idea), E per autorizzare l'applicazione, per cui potresti modificare il codice sorgente di OAuth1, ma sinceramente se vuoi usare CURL per fare TUTTO... stai pensando a questo nel modo sbagliato, e dovresti trovare un'altra soluzione o metodo.

@Dan9 con quello che stai cercando di fare, dovresti usare OAuth2 server invece di OAuth1, principalmente perché OAuth2 ha nuove funzionalità incluso il tipo di concessione Client Credential, che evita di dover passare attraverso tutti questi passaggi http://bshaffer.github.io/oauth2-server-php-docs/grant-types/client-credentials/

@Dan9 se sei assolutamente determinato a ottenere aiuto per farlo tramite OAuth1, usando CURL, penso sia possibile con qualche modifica al codice, ma come ho detto, questo significa che devi salvare USERNAME e PASSWORD di un utente nel file PHP. Se per te va bene, fammelo sapere e scriverò un tutorial per farlo usando CURL, non voglio perdere tempo a scrivere il tutorial se poi opterai per OAuth2 o non ne avrai più bisogno

@Dan9 beh... è proprio questo il punto... se vuoi usare OAuth1, devi associare un Account Utente WordPress. Fondamentalmente pensa al Token di Accesso come a una chiave API... la "Chiave API" deve essere associata a un account utente... ora sta a te decidere se usare qualche account standard che hai configurato.. ma in ogni caso quando usi OAuth1 DEVE essere associato a un account utente, da qui il lungo processo per ottenere il token di accesso.

Ecco perché ho consigliato di usare OAuth2 perché puoi utilizzare il tipo di concessione client credentials, dove poi fai semplicemente una chiamata CURL con quelle credenziali, e ti restituisce un token di accesso (senza bisogno di passare attraverso il lungo processo di autorizzazione). Ecco tutti i tipi di concessione di OAuth2: http://bshaffer.github.io/oauth2-server-php-docs/overview/grant-types/

Aggiungo questa come un'altra risposta per aiutarti a capire come fare questo. Fondamentalmente, come menzionato nei miei commenti, se intendi usare OAuth1 DEVI associarlo a un account utente, non c'è modo di aggirare questo.
Per prima cosa devi usare CURL per accedere al sito con un nome utente e password per WordPress, memorizzare il cookie in modo da poterlo usare nella tua chiamata CURL a OAuth (assicurati di aggiornare la tua chiamata CURL per includere il cookie):
https://stackoverflow.com/questions/724107/wordpress-autologin-using-curl-or-fsockopen-in-php
Poi fai la chiamata a OAuth usando CURL con il Client ID e il Client Secret, per ottenere il token oauth temporaneo e il segreto (Request Token)
Per fare questa chiamata (e la chiamata per ottenere il token di accesso), devi configurare correttamente la tua chiamata CURL. Vedi alla fine di questa risposta per il codice e i riferimenti.
Dopo aver ottenuto il token oauth temporaneo e il segreto (Request Token), fai una chiamata CURL POST a questo URL del tuo sito:
http://website.com/oauth1/authorize
Dovrai quindi estrarre tutti i valori dall'HTML restituito per la pagina di autorizzazione, e poi inviare il tuo POST all'URL dell'azione del form.
https://stackoverflow.com/questions/35363815/how-to-get-a-value-input-from-html-returned-of-curl
In particolare, questi devono essere inclusi nei tuoi dati POST per completare l'"autorizzazione" POSTando a http://domain.com/wp-login.php?action=oauth1_authorize
_wpnonce
-- Questo è il valore nonce per il form da inviare, questo DEVE essere estratto dall'input HTML e inviato con il tuo POSTconsumer
-- Questo è un input nascosto nell'HTML (questo è un riferimento a un Post ID quindi devi estrarlo dall'input HTMLoauth_token
-- Questo è un input nascosto nell'HTML (ma dovresti già averlo)wp-submit
-- Questo deve essere impostato al valoreauthorize
Ecco un esempio di HTML generato per la pagina di autenticazione:
<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">Connetti My Auth</h2>
<div class="login-info">
<p>Ciao <strong>admin</strong>,<br/> "My OAuth Demo" vorrebbe connettersi a 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&oauth_consumer_key=TUPFNj1ZTd8u&oauth_token=i1scugFXyPENniCP4kABKtGb&oauth_token_secret=gzqW47pHG0tilFm9WT7lUgLoqN2YqS6tFFjUEiQoMgcmG2ic" /> <p class="submit">
<button type="submit" name="wp-submit" value="authorize" class="button button-primary button-large">Autorizza</button>
<button type="submit" name="wp-submit" value="cancel" class="button button-large">Annulla</button>
</p>
</form>
Dopo aver fatto il POST con tutti quei valori/dati, questo è l'HTML che verrà restituito con il codice di autorizzazione (quindi devi estrarre il valore dal blocco <code>
:
<div id="login">
<h1><a href="https://wordpress.org/" title="Powered by WordPress" tabindex="-1">Example Site</a></h1>
<p>Il tuo token di verifica è <code>yGOYFpyawe8iZmmcizqVIw3f</code></p> <p id="backtoblog"><a href="http://website.com/">← Torna a Example Site</a></p>
</div>
Una volta che hai il token di verifica, puoi fare una chiamata a /oauth1/access
usando il token di verifica, il token oauth e il segreto del token oauth. Il token di verifica deve essere inserito nei dati POST come oauth_verifier
Questo restituirà il tuo nuovo e permanente Access Token, e VOILÀ!
Esempio di Codice CURL
Di seguito è riportato un esempio di codice per fare la chiamata CURL, la parte più importante è come viene generata la oauth_signature
:
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;
}
// Aggiungi request, authorize, ecc. alla fine dell'URL in base alla chiamata che stai facendo
$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);
Questo sito spiega esattamente come codificare la firma OAuth e come inviarla usando CURL (consiglio di leggere l'intera pagina): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own-data/
Altre risorse sulla generazione della firma OAuth1: https://stackoverflow.com/questions/24613277/oauth-signature-generation-using-hmac-sha1
Altre Risorse: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/

Come posso ottenere Client ID e Client secret e associarli a un utente valido? Attualmente solo gli amministratori possono creare una nuova app e ciò avviene esclusivamente tramite la dashboard di amministrazione. A proposito, ho provato a generare oauth_signature
come mi hai detto ma, in qualche modo, la risposta è sempre json_oauth1_signature_mismatch
.

@Dan9 sì è corretto, gli amministratori devono creare l'app, altrimenti sarebbe un enorme problema di sicurezza consentire la creazione di app da parte di utenti anonimi. Ecco alcuni siti riguardanti la firma http://wordpress.stackexchange.com/questions/185511/oauth-signature-does-not-match https://github.com/WP-API/OAuth1/issues/34 https://github.com/WP-API/OAuth1/issues/27

So che mi sto unendo un po' in ritardo, ma puoi usare wp_remote_get e _post?
Sto recuperando e inviando contenuti con la mia installazione WordPress utilizzandoli:
Questa è l'idea generale dal codex di WordPress:
$response = wp_remote_post( $url, array(
'body' => $data,
'httpversion' => '1.0',
'sslverify' => false,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( $username . ':' . $password ),
),
) );
Ecco un esempio più specifico:
$url='http://WWW.ESEMPIOQUI.';
$response = wp_remote_post( $url, array(
'method' => 'POST',
'timeout' => 45,
'redirection' => 5,
'httpversion' => '1.0', //necessario per ottenere una risposta
'blocking' => true,
'headers' => array('Authorization' => 'Basic ' . base64_encode( 'ILMIO TOKENID' . ':' . '' )),
'body' => $body // in array
'cookies' => array()
)
);
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
echo "Qualcosa è andato storto: $error_message";
} else {
// echo 'Risposta:<pre>';
// print_r( $response );
// echo '</pre>';
$responseBody = json_decode($response['body'],true);
echo $responseBody['message'];
}
}
}
Il trucco sta nel codificare nome utente e password. Spesso, a seconda dell'API, il nome utente e la password saranno vuoti o saranno i tuoi token.
Ad esempio, nel mio caso specifico sopra, gli header erano
'headers' => array('Authorization' => 'Basic ' . base64_encode( 'ILMIOTOKENID' . ':' . '' ))
e ho lasciato la password vuota. Questo però dipende dal sistema API che stai utilizzando.

Aggiornamento: Da quello che ho letto, è necessario eseguire multiple richieste curl per ottenere l'access_token, che poi utilizzerai per eseguire la query
- Acquisizione Credenziali Temporanee: Il client ottiene un set di credenziali temporanee dal server.
- Autorizzazione: L'utente "autorizza" il token di richiesta ad accedere al proprio account.
- Scambio Token: Il client scambia le credenziali temporanee a breve durata con un token a lunga durata.
