¿Cómo usar la autenticación OAuth con REST API a través de comandos CURL?

18

Estoy tratando de usar WordPress Rest Api con autenticación para obtener más datos de la API. He instalado el complemento Oauth, el complemento rest-api y obtuve credenciales de API de WP-CLI.

He descubierto cómo acceder a los datos sin autorización. Esto funciona:

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

Pero no puedo entender cómo autenticarme con credenciales. Aquí está mi intento. No estoy seguro de si "clave" y "secreto" son correctos.

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

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

¿Cómo puedo hacer que esto funcione? Gracias.

JediTricks007
fuente
2
Las cosas no son tan fáciles. He estado tratando de escribir una respuesta pero es bastante largo. Puede comenzar leyendo los documentos, especialmente El flujo de autorización . Esta publicación también tiene un gran tutorial .
cybmeta

Respuestas:

10

Vamos paso a paso aquí. Parece que está tratando de usar OAuth solo para la autenticación, pero antes de poder hacerlo necesita obtener el token de acceso que se usará para autenticarse cuando realice sus llamadas a la API.

Debido a que está utilizando la versión 1 de OAuth, para obtener el token de acceso debe hacer lo siguiente:

  1. Primero, configure una aplicación, realice una llamada al sitio para obtener el token de solicitud (credenciales temporales) utilizando el ID de cliente y el secreto de la aplicación
  2. En segundo lugar, realice una llamada al sitio para autorizar la aplicación con el token de solicitud desde el primer paso (frente al usuario, consulte a continuación).
  3. Tercero, después de que se haya completado la autorización, debe hacer una llamada al sitio para obtener el token de acceso (ahora que la aplicación ha sido autorizada)

Recomiendo usar Postman para los primeros pasos, ya que solo deben completarse una vez. Postman también se encargará de generar el timestamp, noncey oauth signature, por lo tanto, si no está utilizando una biblioteca OAuth, entonces absolutamente debe usar Postman. Una vez que tenga su Token de acceso , puede hacer las llamadas a través de CURL sin ninguna biblioteca.

https://www.getpostman.com/

Primer paso (aplicación de configuración)

Instale el complemento WP OAuth 1, actívelo y luego pase al elemento del menú en Usuarios> Aplicaciones . Agregue una nueva aplicación, complete el nombre y la descripción. Para la devolución de llamada, ya sea la URL para redirigir al usuario (después de la autorización) o ooppara el flujo fuera de banda que redirigirá a una página interna que muestra el token verificador (en lugar de redirigir).

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

Para continuar con el segundo paso, se debe hacer una llamada a su sitio, utilizando el ID de cliente y el Secreto de cliente de la aplicación creada, para obtener credenciales temporales (Token de solicitud).

Abra Postman, cree una nueva llamada a http://website.com/oauth1/request, haga clic en la pestaña Autorización, seleccione OAuth 1.0 del menú desplegable, ingrese la Clave de cliente, Secreto de cliente, configure el método de firma en HMAC-SHA1, habilite agregar parámetros al encabezado, codifique oauth firma , luego haga clic en Actualizar solicitud

Cartero OAuth1 Solicitud

Postman generará automáticamente la firma, el nonce y la marca de tiempo para usted, y los agregará al encabezado (puede verlos en la pestaña Encabezados).

Haga clic en Enviar y debería obtener una respuesta que incluya oauth_tokeny oauth_token_secret: Cartero OAuth1 Solicitar respuesta

Estos valores se utilizarán en el siguiente paso para autorizar la aplicación en su cuenta de usuario de WordPress.

Segundo paso (autorizar la solicitud)

El paso de autorización solo debe completarse una vez, este paso está orientado al usuario y el que todos conocen. Este paso es obligatorio porque está utilizando OAuth1 y la aplicación debe estar asociada a una cuenta de usuario de WordPress. Piense en cuándo un sitio le permite iniciar sesión con Facebook ... lo dirigen a Facebook donde inicia sesión y hace clic en "Autorizar" ... esto debe hacerse, solo a través de su sitio de WordPress.

Recomiendo usar su navegador web para este paso, ya que puede configurar fácilmente las variables en URL, y esto proporciona la página "Autorizar" para autorizar la aplicación.

Abra su navegador web y escriba la URL de su sitio, así: http://website.com/oauth1/authorize

Ahora agregue a esta URL, oauth_consumer_key(ID de cliente) oauth_tokeny oauth_token_secret(del paso anterior). En mi ejemplo, esta es la URL completa:

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

OAuth1 Autorizar Solicitud

Una vez que haga clic en Autorizar, obtendrá otra pantalla con el token de verificación. En mi ejemplo, este es el token de verificación devueltoE0JnxjjYxc32fMr2AF0uWsZm

Tercer paso (obtener token de acceso)

Ahora que hemos autorizado la aplicación, tenemos que hacer una última llamada para obtener el token de autorización que se utilizará para hacer todas sus llamadas API. Al igual que en el primer paso, usaré Postman (porque se requiere que la firma sea HMAC-SHA1), y hace que sea 100 veces más fácil completar estos pasos.

Abra Postman nuevamente y cambie la URL a http://website.com/oauth1/access

Asegúrese de agregar el token y el token secreto (valores del primer paso), luego haga clic en Parámetros para mostrar los cuadros debajo de la URL. A la izquierda, escriba oauth_verifier y a la derecha, ingrese el código del segundo paso, el token de verificación

Paso de acceso del cartero OAuth1

Asegúrese de hacer clic en Solicitud de actualización, luego haga clic en Enviar, y debería recibir una respuesta oauth_tokeny oauth_token_secret... ¡esto es lo que necesita para hacer sus llamadas a la API! Deseche los originales del paso 1, guárdelos en su código o en otro lugar seguro.

Cartero OAuth1 Respuesta de acceso

Luego puede hacer una llamada API a su sitio, configurando los encabezados con el token devuelto y el token secreto.

Puede pasar esto de varias maneras, a través del encabezado de autorización, en los parámetros GET o POST (si está codificado como application / x-www-form-urlencoded). Tenga en cuenta que DEBE pasar la firma, la marca de tiempo y el nonce. No me di cuenta de cuánto tiempo me llevaría esta respuesta, así que lo actualizaré mañana con un ejemplo sobre cómo hacerlo con su código.

Recomiendo instalar el registro Rest API para que pueda ver el registro de las llamadas API y ver lo que se envió, devolvió, etc. Esto ayudará enormemente a la depuración.

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

sMyles
fuente
Lo sé, hay muchos tutoriales con Postman o herramientas similares, pero no puedo encontrar ningún tutorial que haga todo el proceso con las funciones de CURL, me refiero al código PHP puro. Eso es lo que yo quiero.
MinhTri
@ Dan9 TBH eso no es realmente posible ... al menos no con OAuth1, principalmente porque tienes que AUTORIZAR la aplicación con una cuenta de usuario. Todos los demás pasos son fáciles de hacer con CURL, el problema es usar CURL para iniciar sesión como usuario de WordPress (lo que significa que necesita almacenar credenciales en su archivo PHP, lo cual NO es una buena idea), y autorizar la aplicación, que usted podría modificar la base de código OAuth1, pero sinceramente, si desea utilizar CURL para hacer TODO ... está pensando en esto de manera incorrecta, y debería encontrar otra solución o método.
sMyles
@ Dan9 con lo que está intentando hacer, debe usar el servidor OAuth2 en lugar de OAuth1, principalmente porque el hecho de que OAuth2 tiene nuevas características, incluido el tipo de concesión de Credencial de cliente, que evita tener que seguir todos estos pasos bshaffer.github.io / oauth2-server-php-docs / grant-types /…
sMyles
@ Dan9 si está 100% decidido a obtener ayuda para hacer esto a través de OAuth1, usando CURL, creo que es posible con algunos hacks de código, pero como mencioné, esto significa que debe guardar el NOMBRE DE USUARIO y la CONTRASEÑA de un usuario al archivo PHP. Si estás de acuerdo con eso, házmelo saber y escribiré un tutorial para hacerlo usando CURL, no quiero pasar el tiempo escribiendo un tutorial si vas a usar OAuth2 o ya no lo necesitas
sMyles
@ Dan9 bueno ... eso es todo ... si vas a usar OAuth1, tienes que asociar una cuenta de usuario de WordPress. Básicamente, piense en el token de acceso como una clave API ... la "clave API" tiene que estar asociada con una cuenta de usuario ... ahora si usa alguna cuenta estándar que configure depende de usted ... pero independientemente de cuándo use OAuth1 DEBE estar asociado con una cuenta de usuario, de ahí el largo proceso para obtener el token de acceso.
sMyles
2

Agregando esto como otra respuesta para ayudarlo a descubrir cómo hacer esto. Básicamente, como se menciona en mis comentarios, si va a usar OAuth1 DEBE asociarlo con una cuenta de usuario, no hay forma de evitarlo.

Primero debe usar CURL para iniciar sesión en el sitio con una contraseña de nombre de usuario para WordPress, almacenar la cookie para poder usarla en su llamada CURL a OAuth (asegúrese de actualizar su llamada CURL para incluir la cookie):

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

Luego realice la llamada a OAuth usando CURL con el ID de cliente y el Secreto de cliente, para obtener el token y secreto temporal de Oauth (Token de solicitud)

Para realizar esta llamada (y la llamada para obtener el token de acceso), debe configurar su llamada CURL correctamente. Vea el final de esta respuesta para el código y las referencias.

Después de obtener el token o secreto temporal oauth (Token de solicitud), realice una llamada CURL POST a esta URL de su sitio:

http://website.com/oauth1/authorize

A continuación, deberá extraer todos los valores del HTML devuelto para la página de autorización y luego enviar su propia POST a la URL de acción del formulario.

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

Específicamente, estos deben incluirse en sus datos POST para completar la "autorización" POSTing to http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Este es el valor nonce para el formulario que se enviará, DEBE extraerse de la entrada HTML y enviarse con su POST

    consumer - Esta es una entrada oculta en el HTML (esta es una referencia a una ID de publicación, por lo que debe extraerla de la entrada HTML

    oauth_token - Esta es una entrada oculta en el HTML (pero también debería tener esto)

    wp-submit - Esto debe establecerse en el valor authorize

Aquí hay un ejemplo de HTML generado para la página de autenticación:

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

Después de realizar la POST con todos esos valores / datos, este es el HTML que se devolverá con el código de autorización (por lo que debe extraer el valor desde el interior del <code>bloque:

<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 vez que tenga el token de verificación, puede llamar para /oauth1/accessusar el token de verificación, el token oauth y el secreto del token oauth. El token de verificación debe colocarse en los datos POST comooauth_verifier

¡Eso devolverá su token de acceso nuevo y permanente, y VOILA!

Código CURL de ejemplo

A continuación se muestra un código de ejemplo para hacer la llamada CURL, la parte más importante es cómo oauth_signaturese genera:

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

Este sitio le dice exactamente cómo codificar la firma OAuth y cómo enviar usando CURL (recomiendo leer la página completa): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- datos/

Más recursos para generar la firma OAuth1: /programming/24613277/oauth-signature-generation-using-hmac-sha1

Otros recursos: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/

sMyles
fuente
¿Cómo puedo obtener la identificación del cliente y el secreto del cliente y asociarlo con un usuario válido? Actualmente, solo los administradores pueden crear una nueva aplicación y esto solo sucede a través del panel de administración. Por cierto, he tratado de generar oauth_signaturecomo me dijiste, pero, de alguna manera, la respuesta es siempre json_oauth1_signature_mismatch.
MinhTri
@ Dan9 sí, eso es correcto, los administradores tienen que crear la aplicación, de lo contrario sería un gran problema de seguridad que permitiría que las aplicaciones sean creadas por usuarios anónimos. Aquí hay algunos sitios sobre la firma wordpress.stackexchange.com/questions/185511/… github.com/WP-API/OAuth1/issues/34 github.com/WP-API/OAuth1/issues/27
sMyles
0

Actualización: por lo que he leído, debe hacer múltiples rizos para obtener el acceso_token, que luego usa para hacer la consulta

  • Adquisición de credenciales temporales: el cliente obtiene un conjunto de credenciales temporales del servidor.
  • Autorización: el usuario "autoriza" el token de solicitud para acceder a su cuenta.
  • Intercambio de tokens: el cliente intercambia las credenciales temporales de corta duración por un token de larga duración.

flujo del servidor oauth1

juz
fuente
0

Sé que voy a llegar un poco tarde, pero ¿puedes usar wp_remote_get y _post?

Estoy tirando y publicando contenido con mi instalación de WordPress usándolos:

Esta es la idea general del códice de wordpress:

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

Aquí hay un ejemplo más específico:

$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'];

    }
    }
}

El truco es codificar el nombre de usuario y pw. Ahora, a menudo, el tiempo depende del nombre de usuario API y pw estará en blanco o serán sus tokens.

así, por ejemplo, en mi ejemplo específico anterior, los encabezados eran

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

y dejé pw en blanco. Sin embargo, eso depende del sistema API que esté utilizando.

Rudtek
fuente