Come utilizzare l'autenticazione OAuth con l'API REST tramite i comandi CURL?


18

Sto cercando di utilizzare WordPress Rest Api con autenticazione per ottenere più dati dall'API. Ho installato il plug-in Oauth, il plug-in rest-api e le credenziali API ottenute da WP-CLI.

Ho capito come accedere ai dati senza autorizzazione. Questo funziona:

// 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>

Ma non riesco a capire come autenticarmi con le credenziali. Ecco il mio tentativo. Non sono sicuro che "chiave" e "segreto" siano corretti.

// 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>

L'output è

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

Come posso farlo funzionare? Grazie.


2
Le cose non sono così facili. Ho cercato di scrivere una risposta ma è piuttosto lungo. Puoi iniziare leggendo i documenti, in particolare The Authorization Flow . Questo post ha anche un ottimo tutorial .
cybmeta,

Risposte:


10

Andiamo passo dopo passo qui. Sembra che tu stia cercando di utilizzare OAuth solo per l'autenticazione, ma prima di poterlo fare devi ottenere il token di accesso che verrà utilizzato per autenticare quando effettui le chiamate API.

Poiché utilizza OAuth versione 1, per ottenere il token di accesso è necessario effettuare le seguenti operazioni:

  1. Innanzitutto, imposta un'applicazione, effettua una chiamata al sito per ottenere il token di richiesta (credenziali temporanee) utilizzando l'ID client e il segreto per l'applicazione
  2. In secondo luogo, effettuare una chiamata al sito per autorizzare l'applicazione con il token di richiesta dal primo passaggio (rivolto verso l'utente, vedere di seguito).
  3. In terzo luogo, dopo che l'autorizzazione è stata completata, si effettua quindi una chiamata al sito per ottenere il token di accesso (ora che l'applicazione è stata autorizzata)

Consiglio di usare Postman per i primi passi, perché devono essere completati una sola volta. Postman gestirà anche la generazione di timestamp, noncee oauth signaturequindi, se non stai usando una libreria OAuth, allora dovresti assolutamente usare Postman. Una volta ottenuto il token di accesso, è possibile effettuare chiamate tramite CURL senza librerie.

https://www.getpostman.com/

Primo passo (applicazione di installazione)

Installa il plugin WP OAuth 1, attiva, quindi vai alla voce di menu in Utenti> Applicazioni . Aggiungi nuova applicazione, compila il nome e la descrizione. Per richiamare l'URL a cui reindirizzare l'utente (dopo l'autorizzazione) o oopper il flusso fuori banda che reindirizzerà a una pagina interna che visualizza il token del verificatore (anziché reindirizzare).

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

Per procedere al secondo passaggio, è necessario effettuare una chiamata al proprio sito, utilizzando l' ID client e il segreto client dall'applicazione creata, per ottenere credenziali temporanee (token richiesta).

Apri Postman, crea una nuova chiamata a http://website.com/oauth1/request, fai clic sulla scheda Autorizzazione, seleziona OAuth 1.0 dal menu a discesa, inserisci la chiave client, il segreto client, imposta il metodo di firma su HMAC-SHA1, abilita aggiungi parametri all'intestazione, codifica la firma oauth , quindi fai clic su Richiesta di aggiornamento

Richiesta PostA OAuth1

Postman genererà automaticamente la firma, il nonce e il timestamp per te e li aggiungerà all'intestazione (puoi visualizzare nella scheda Intestazioni).

Fai clic su Invia e dovresti ottenere una risposta che include oauth_tokene oauth_token_secret: Postman OAuth1 Richiedi risposta

Questi valori verranno utilizzati nel passaggio successivo per autorizzare l'applicazione con l'account utente di WordPress.

Secondo passo (autorizzare l'applicazione)

Il passaggio di autorizzazione deve essere completato solo una volta, questo passaggio è rivolto all'utente e quello che tutti conoscono. Questo passaggio è necessario perché stai utilizzando OAuth1 e l'applicazione deve essere associata a un account utente WordPress. Pensa a quando un sito ti consente di accedere con Facebook ... ti indirizzano a Facebook dove accedi e fai clic su "Autorizza" ... questo deve essere fatto, solo attraverso il tuo sito WordPress.

Ti consiglio di utilizzare il tuo browser Web per questo passaggio, poiché puoi semplicemente impostare le variabili nell'URL e questo fornisce 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 questo URL, oauth_consumer_key(ID client) oauth_tokene 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

OAuth1 Autorizza l'applicazione

Dopo aver fatto clic su Autorizza, verrà visualizzata un'altra schermata con il token di verifica. Nel mio esempio questo è il token di verifica restituitoE0JnxjjYxc32fMr2AF0uWsZm

Terzo passaggio (ottieni il token di accesso)

Ora che abbiamo autorizzato l'applicazione, è necessario effettuare un'ultima chiamata per ottenere il token di autorizzazione che verrà utilizzato per effettuare tutte le chiamate API. Proprio come il primo passo che userò Postman (perché la firma deve essere HMAC-SHA1) e rende 100 volte più facile completare questi passaggi.

Apri di nuovo Postman e modifica l'URL in http://website.com/oauth1/access

Assicurati di aggiungere il token e il token segreto (valori dal primo passaggio), quindi fai clic su Params per mostrare le caselle sotto l'URL. A sinistra digita oauth_verifier e a destra, inserisci il codice dal secondo passaggio, il token di verifica

Postman OAuth1 Step di accesso

Assicurati di fare clic su Richiesta di aggiornamento, quindi fai clic su Invia e dovresti ottenere una risposta con oauth_tokene oauth_token_secret... questo è ciò di cui hai bisogno per effettuare le tue chiamate API! Scarta quelli originali dal passaggio 1, salvali nel tuo codice o in un altro posto sicuro.

Postman OAuth1 Risposta d'accesso

È quindi possibile effettuare una chiamata API al sito, impostando le intestazioni con il token restituito e il token segreto.

Puoi passare questo in diversi modi, tramite l'intestazione 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 avevo capito quanto tempo ci sarebbe voluta questa risposta, quindi lo aggiornerò domani con un esempio di come farlo con il tuo codice.

Consiglio vivamente di installare il registro API Rest in modo da poter visualizzare il registro delle chiamate API e vedere cosa è stato inviato, restituito, ecc. Ciò contribuirà enormemente al debug.

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


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

@ Dan9 TBH non è davvero possibile ... almeno non con OAuth1, principalmente perché devi AUTORIZZARE l'applicazione con 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 è necessario archiviare le credenziali nel file PHP che NON è una buona idea), E di autorizzare l'applicazione, che si potrebbe modificare la base di codice OAuth1, ma onestamente se vuoi usare CURL per fare TUTTO ... stai pensando a questo nel modo sbagliato e dovresti trovare un'altra soluzione o metodo.
sMyles,

@ Dan9 con quello che stai cercando di fare, dovresti usare il server OAuth2 invece di OAuth1, principalmente perché il fatto che OAuth2 ha nuove funzionalità tra cui il tipo di concessione Credenziali client, che evita di dover passare attraverso tutti questi passaggi bshaffer.github.io / oauth2-server-php-docs / grant-types /…
sMyles

@ Dan9 se hai il 100% di aiuto per farlo tramite OAuth1, usando CURL, penso che sia possibile con alcuni hack di codice, ma come ho già detto, questo significa che devi salvare USERNAME e PASSWORD di un utente al file PHP. Se stai bene, fammelo sapere e scriverò un tutorial per farlo usando CURL, non voglio passare il tempo a scrivere tutorial se vai con OAuth2 o non ne hai più bisogno
Stili

@ Dan9 bene ... questo è tutto ... se hai intenzione di utilizzare 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 se usi un account standard che hai impostato dipende da te .. ma indipendentemente da quando usi OAuth1 DEVE essere associato a un account utente, quindi alla lunga procedura per ottenere il token di accesso.
sMyles,

2

Aggiungendo questa come un'altra risposta per darti aiuto per capire come farlo. Fondamentalmente, come menzionato nei miei commenti, se hai intenzione di utilizzare OAuth1 DEVI associarlo a un account utente, in nessun caso.

Per prima cosa devi utilizzare CURL per accedere al sito con una password nome utente per WordPress, memorizzare il cookie in modo da poterlo utilizzare nella tua chiamata CURL a OAuth (assicurati di aggiornare la tua chiamata CURL per includere il cookie):

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

Quindi effettua la chiamata a OAuth utilizzando CURL con l'ID client e il segreto client, per ottenere il token oauth temporaneo e segreto (Richiedi token)

Per effettuare questa chiamata (e la chiamata per ottenere il token di accesso), è necessario impostare correttamente la chiamata CURL. Vedi fine di questa risposta per codice e riferimenti.

Dopo aver ottenuto il token oauth temporaneo e segreto (Richiedi token), effettua una chiamata POST CURL a questo URL del tuo sito:

http://website.com/oauth1/authorize

Sarà quindi necessario estrarre tutti i valori dall'HTML restituito per la pagina di autorizzazione, quindi inviare il proprio POST all'URL dell'azione del modulo.

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

In particolare, questi devono essere inclusi nei dati POST per completare il POST "autorizzazione" http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Questo è il valore nonce per il modulo da inviare, DEVE essere estratto dall'input HTML e inviato con il tuo POST

    consumer - Questo è un input nascosto nell'HTML (si tratta di un ID post, quindi è necessario estrarlo dall'input HTML

    oauth_token - Questo è un input nascosto nell'HTML (ma dovresti già averlo)

    wp-submit - Questo deve essere impostato sul valore authorize

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">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>

Dopo aver effettuato il POST con tutti quei valori / dati, questo è l'HTML che verrà restituito con il codice di autorizzazione (quindi è necessario estrarre il valore dall'interno del <code>blocco:

<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>

Una volta che hai il token di verifica, puoi quindi effettuare una chiamata /oauth1/accessusando il token di verifica, il token oauth e il token segreto oauth. Il token di verifica deve essere inserito nei dati POST comeoauth_verifier

Ciò restituirà il tuo token di accesso nuovo e permanente e VOILA!

Esempio di codice CURL

Di seguito è riportato un codice di esempio per effettuare la chiamata CURL, la parte più importante è come oauth_signatureviene generato:

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);

Questo sito spiega esattamente come codificare la firma OAuth e come inviare utilizzando CURL (consiglio di leggere l'intera pagina): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- dati/

Altre risorse sulla generazione della firma OAuth1: /programming/24613277/oauth-signature-generation-using-hmac-sha1

Altre risorse: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/


Come posso mantenere segreto l'ID client e il client e associarlo a un utente valido? Attualmente, solo gli amministratori possono creare una nuova app e ciò avviene solo tramite la dashboard di amministrazione. A proposito, ho provato a generare oauth_signaturecome hai detto ma, in qualche modo, la risposta è sempre json_oauth1_signature_mismatch.
MinhTri,

@ Dan9 sì, è corretto, gli amministratori devono creare l'app, altrimenti sarebbe un enorme problema di sicurezza che consente alle app di essere create da utenti anonimi. Ecco alcuni siti riguardanti la firma wordpress.stackexchange.com/questions/185511/… github.com/WP-API/OAuth1/issues/34 github.com/WP-API/OAuth1/issues/27
sMyles

0

Aggiornamento: da quello che ho letto, devi fare più riccioli per ottenere access_token, che poi usi per fare la query

  • Acquisizione credenziali temporanee: il client ottiene una serie 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 di breve durata con un token di lunga durata.

flusso del server oauth1


0

So che ci arrivo un po 'tardi, ma puoi usare wp_remote_get e _post?

Sto estraendo e pubblicando contenuti con la mia installazione di wordpress utilizzandoli:

Questa è l'idea generale del codice 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.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'];

    }
    }
}

Il trucco sta nel codificare il nome utente e pw. Ora spesso a seconda del nome utente API e pw saranno vuoti o saranno i tuoi token.

così per esempio nel mio esempio specifico sopra, le intestazioni erano

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

e ho lasciato pw vuoto. Dipende dal sistema API che stai utilizzando.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.