Como usar a autenticação OAuth com a API REST por meio de comandos CURL?

18

Estou tentando usar a API de descanso do WordPress com autenticação para obter mais dados da API. Instalei o plug-in Oauth, o plug-in rest-api e obtive credenciais de API do WP-CLI.

Eu descobri como acessar dados sem autorização. Isso 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>

Mas não consigo descobrir como autenticar com credenciais. Aqui está a minha tentativa. Não tenho certeza se "chave" e "segredo" estão corretas.

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

A saída é

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

Como posso fazer isso funcionar? Obrigado.

JediTricks007
fonte
2
As coisas não são tão fáceis. Eu tenho tentado escrever uma resposta, mas é bastante longo. Você pode começar lendo os documentos, especialmente o fluxo de autorização . Este post também tem um ótimo tutorial .
cybmeta 01/01

Respostas:

10

Vamos passo a passo aqui. Parece que você está tentando usar o OAuth apenas para autenticação, mas para poder fazer isso, é necessário obter o token de acesso, que será usado para autenticar quando você fizer suas chamadas de API.

Como está usando o OAuth versão 1, para obter o token de acesso, faça o seguinte:

  1. Primeiro, configure um aplicativo, faça uma chamada para o site para obter o token de solicitação (credenciais temporárias) usando a ID do cliente e o segredo do aplicativo
  2. Segundo, ligue para o site para autorizar o aplicativo com o token de solicitação desde o primeiro passo (voltado para o usuário, veja abaixo).
  3. Terceiro, após a conclusão da autorização, você faz uma ligação para o site para obter o token de acesso (agora que o aplicativo foi autorizado)

Eu recomendo usar o Postman para as primeiras etapas, porque elas precisam ser concluídas apenas uma vez. O Postman também manipulará a geração de timestamp, noncee oauth signature, portanto, se você não estiver usando uma biblioteca OAuth, deverá usar absolutamente o Postman. Depois de ter seu token de acesso, você poderá fazer chamadas via CURL sem nenhuma biblioteca.

https://www.getpostman.com/

Primeira etapa (aplicativo de configuração)

Instale o plug-in WP OAuth 1, ative e vá para o item de menu em Usuários> Aplicativos . Adicione um novo aplicativo, preencha o nome e a descrição. Para retorno de chamada, o URL para o qual redirecionar o usuário (após a autorização) ou oopfluxo Out-of-Band que será redirecionado para uma página interna que exibe o token do verificador (em vez de redirecionar).

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

Para prosseguir para a segunda etapa, é necessário fazer uma chamada para o seu site, usando o ID do cliente e o Segredo do cliente do do aplicativo criado, para obter credenciais temporárias (Request Token).

Abra o Postman, crie uma nova chamada para http://website.com/oauth1/request, clique na guia Autorização, selecione OAuth 1.0 no menu suspenso, digite a Chave do cliente, Segredo do cliente, defina o método de assinatura como HMAC-SHA1, habilite adicionar parâmetros ao cabeçalho, codifique a assinatura oauth e clique em Atualizar solicitação

Solicitação de carteiro OAuth1

O Postman gera automaticamente a assinatura, o nonce e o carimbo de data e hora para você e os adiciona ao cabeçalho (você pode visualizar na guia Cabeçalhos).

Clique em Enviar e você deverá obter uma resposta que inclua oauth_tokene oauth_token_secret: Carteiro OAuth1 Solicitar resposta

Esses valores serão usados ​​na próxima etapa para autorizar o aplicativo em sua conta de usuário do WordPress.

Segunda etapa (autorizar inscrição)

A etapa de autorização precisa ser concluída apenas uma vez; essa etapa é voltada para o usuário e aquela que todos estão familiarizados. Esta etapa é necessária porque você está usando o OAuth1 e o aplicativo precisa estar associado a uma conta de usuário do WordPress. Pense em quando um site permite que você faça login no Facebook ... eles o direcionam para o Facebook onde você faz login e clica em "Autorizar" ... isso precisa ser feito, apenas através do seu site WordPress.

Eu recomendo usar o navegador da Web para esta etapa, pois você pode facilmente definir as variáveis ​​no URL, e isso fornece a página "Autorizar" para autorizar o aplicativo.

Abra seu navegador da web e digite o URL do seu site, assim: http://website.com/oauth1/authorize

Agora adicione este URL oauth_consumer_key(ID do cliente) oauth_tokene oauth_token_secret(da etapa anterior). No meu exemplo, este é o URL completo:

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

Autorizar aplicativo OAuth1

Depois de clicar em Autorizar, você receberá outra tela com o token de verificação. No meu exemplo, este é o token de verificação retornadoE0JnxjjYxc32fMr2AF0uWsZm

Terceira etapa (obter token de acesso)

Agora que autorizamos o aplicativo, precisamos fazer uma última chamada para obter o Token de Autorização, que será usado para fazer todas as suas chamadas de API. Assim como o primeiro passo, vou usar o Postman (porque é necessário que a assinatura seja o HMAC-SHA1) e torna 100x mais fácil concluir essas etapas.

Abra o Postman novamente e altere o URL para http://website.com/oauth1/access

Certifique-se de adicionar o Token e o Token Secret (valores da primeira etapa) e clique em Params para mostrar as caixas abaixo da URL. À esquerda, digite oauth_verifier e à direita, digite o código da segunda etapa, o Token de Verificação

Etapa de acesso do carteiro OAuth1

Certifique-se de clicar em Solicitação de atualização, clique em Enviar e você deverá receber uma resposta novamente com ... oauth_tokene oauth_token_secreté com isso que você precisa fazer suas chamadas de API! Descarte os originais da etapa 1, salve-os no seu código ou em outro lugar seguro.

Resposta de acesso do carteiro OAuth1

Você pode fazer uma chamada de API ao seu site, definindo os cabeçalhos com o token retornado e o segredo do token.

Você pode passar isso de várias maneiras, via cabeçalho de autorização, nos parâmetros GET ou POST (se codificado como application / x-www-form-urlencoded). Lembre-se de que DEVE passar a assinatura, o carimbo de data e hora e o nonce. Não sabia quanto tempo essa resposta levaria, então atualizarei isso amanhã com um exemplo de como fazer isso com seu código.

Eu recomendo fortemente a instalação do log da API Rest, para que você possa visualizar o log das chamadas da API e ver o que foi enviado, retornado etc. Isso ajudará na depuração tremendamente.

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

sMyles
fonte
Eu sei, existem muitos tutoriais com o Postman ou ferramentas semelhantes, mas não consigo encontrar nenhum tutorial que faça todo o processo com as funcionalidades CURL, quero dizer, código PHP puro. Isso é o que eu quero.
MinhTri 20/09/16
@ Dan9 TBH, isso não é realmente possível ... pelo menos não com o OAuth1, principalmente porque você precisa AUTORIZAR o aplicativo em uma conta de usuário. Todas as outras etapas são fáceis de executar com o CURL, o problema é usar o CURL para fazer login como usuário do WordPress (o que significa que você precisa armazenar credenciais no seu arquivo PHP, o que NÃO é uma boa ideia) E autorizar o aplicativo, que você poderia modificar a base de código OAuth1, mas honestamente, se você quiser usar CURL para fazer TUDO ... você está pensando sobre isso da maneira errada e deve apresentar outra solução ou método.
precisa saber é
@ Dan9 com o que você está tentando fazer, você deve usar o servidor OAuth2 em vez do OAuth1, principalmente porque o OAuth2 possui novos recursos, incluindo o tipo de concessão de Credencial para Cliente, que evita ter que passar por todas essas etapas bshaffer.github.io / oauth2-server-php-docs / grant-types /…
sMyles 20/09/16
@ Dan9, se você está 100% preparado para obter ajuda com o OAuth1, usando CURL, acho que é possível com alguns hacks de código, mas como mencionei, isso significa que você precisa salvar o USERNAME e PASSWORD de um usuário para o arquivo PHP. Se você estiver bem com isso, informe-me e escreverei mal um tutorial para fazê-lo usando CURL, não queira gastar o tempo escrevendo tutorial se quiser usar o OAuth2 ou não precisar mais disso
sMyles 20/09/16
@ Dan9 bem ... é isso mesmo ... se você for usar o OAuth1, precisará associar uma conta de usuário do WordPress. Pense basicamente no token de acesso como uma chave de API ... a "chave de API" deve ser associada a uma conta de usuário ... agora, se você usa alguma conta padrão, a configuração é sua. Mas, independentemente do uso do OAuth1, DEVE estar associado a uma conta de usuário, daí o processo demorado para obter o token de acesso.
Smyles
2

Adicionando isso como outra resposta para ajudar você a descobrir como fazer isso. Basicamente, como mencionado nos meus comentários, se você for usar o OAuth1, DEVE associá-lo a uma conta de usuário, sem contornar isso.

Primeiro, você precisa usar o CURL para fazer login no site com uma senha de nome de usuário para WordPress, armazenar o cookie para poder usá-lo na sua chamada CURL para OAuth (atualize sua chamada CURL para incluir o cookie):

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

Em seguida, faça a chamada para o OAuth usando CURL com o ID do cliente e o segredo do cliente, para obter o token e o segredo temporários do oauth (Request Token)

Para fazer esta chamada (e a chamada para obter o token de acesso), você precisa configurar sua chamada CURL corretamente. Veja o final desta resposta para código e referências.

Depois de obter o token e o segredo temporários oauth (Request Token), faça uma chamada CURL POST para este URL do seu site:

http://website.com/oauth1/authorize

Você precisará puxar todos os valores do HTML retornado para a página de autorização e, em seguida, enviar seu próprio POST para o URL da ação do formulário.

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

Especificamente, eles precisam ser incluídos nos dados do POST para concluir a "autorização" do POST para http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Este é o valor nonce para o formulário a ser enviado, DEVE ser extraído da entrada HTML e enviado com o seu POST

    consumer - Esta é uma entrada oculta no HTML (é uma referência a um ID da postagem, portanto você deve retirá-la da entrada HTML

    oauth_token - Esta é uma entrada oculta no HTML (mas você também já deve ter)

    wp-submit - Isso precisa ser definido como o valor authorize

Aqui está um exemplo de HTML gerado para a página de autenticação:

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

Depois de fazer o POST com todos esses valores / dados, este é o HTML que será retornado com o código de autorização (portanto, você precisará extrair o valor de dentro do <code>bloco:

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

Depois de ter o token de verificação, você poderá fazer uma chamada para /oauth1/access usar o token de verificação, o token oauth e o segredo do token oauth. O token de verificação precisa ser inserido nos dados do POST comooauth_verifier

Isso retornará seu novo e permanente token de acesso e o VOILA!

Exemplo de código CURL

Abaixo está um código de exemplo para fazer a chamada CURL, sendo a parte mais importante a forma como ela oauth_signatureé gerada:

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 site mostra exatamente como codificar a assinatura OAuth e como enviar usando CURL (eu recomendo a leitura da página inteira): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- dados/

Mais recursos na geração de assinatura OAuth1: /programming/24613277/oauth-signature-generation-using-hmac-sha1

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

sMyles
fonte
Como posso obter o ID do cliente e o segredo do cliente e associá-lo a um usuário válido? Atualmente, apenas os administradores podem criar um novo aplicativo e isso acontece apenas pelo painel do administrador. Btw, eu tentei gerar oauth_signaturecomo você disse, mas, de alguma forma, a resposta é sempre json_oauth1_signature_mismatch.
MinhTri 21/09/16
@ Dan9 Sim, está correto, os administradores precisam criar o aplicativo, caso contrário, isso seria um grande problema de segurança, permitindo que aplicativos fossem criados por usuários anônimos. Aqui estão alguns sites sobre assinatura wordpress.stackexchange.com/questions/185511/… github.com/WP-API/OAuth1/issues/34 github.com/WP-API/OAuth1/issues/27
sMyles
0

Atualização: pelo que li, você precisa fazer vários cachos para obter o access_token, que você usa para fazer a consulta

  • Aquisição de credenciais temporárias: O cliente obtém um conjunto de credenciais temporárias do servidor.
  • Autorização: o usuário "autoriza" o token de solicitação a acessar sua conta.
  • Troca de token: o cliente troca as credenciais temporárias de curta duração por um token de longa duração.

fluxo do servidor oauth1

juz
fonte
0

Eu sei que vou entrar nisso um pouco tarde, mas você pode usar wp_remote_get e _post?

Estou puxando e publicando conteúdo com minha instalação do wordpress usando-os:

Esta é a ideia geral do códice wordpress:

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

Aqui está um exemplo mais 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'];

    }
    }
}

O truque é codificar o nome de usuário e o pw. Agora, muitas vezes o tempo, dependendo do nome de usuário da API e do pw, ficará em branco ou será o seu tokens.

Por exemplo, no meu exemplo específico acima, os cabeçalhos foram

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

e eu deixei pw em branco. Isso depende do sistema de API que você está usando.

Rudtek
fonte