如何通过curl命令将OAuth身份验证与REST API配合使用?

时间:2015-12-27 作者:JediTricks007

我正在尝试将WordPress Rest Api与身份验证结合使用,以从Api中获取更多数据。我已经安装了Oauth插件、RESTAPI插件,并从WP-CLI获得了api凭据。

我已经知道如何在未经授权的情况下访问数据。这项工作:

// 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>
但我不知道如何使用凭据进行身份验证。这是我的尝试。我不确定“key”和“secret”是否正确。

// 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>
输出为

Array
(
    [code] => rest_cannot_read
    [message] => Sorry, you cannot view revisions of this post.
    [data] => Array
        (
            [status] => 401
        )
)
我怎样才能让它工作?非常感谢。

4 个回复
SO网友:sMyles

让我们在这里一步一步走。看起来您正试图使用OAuth进行身份验证,but before you can do so you need to get the Access Token 它将用于在进行API调用时进行身份验证。

因为这是使用OAuth版本1,为了获得Access Token 您必须执行以下操作:

首先,安装一个应用程序,调用站点以获取Request Token (临时凭据)使用应用程序的客户端ID和密码第二,调用站点以使用Request Token 从第一步开始(面向用户,见下文)Access Token (现在该应用程序已获得授权)我建议在前几个步骤中使用Postman,因为它们只需要完成一次。Postman还将处理生成timestamp, nonceoauth signature, 因此,如果您没有使用OAuth库,那么您绝对应该使用Postman。一旦你有了Access Token 您可以通过CURL进行调用,而不需要任何库。

https://www.getpostman.com/

第一步(安装应用程序)

安装WP OAuth 1插件,激活,然后转到下面的菜单项Users > Applications. 添加新应用程序,填写名称和说明。对于回调,可以是将用户重定向到的URL(授权后),或者oop 对于带外流,将重定向到显示验证器令牌的内部页面(而不是重定向)。

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

要继续第二步,需要使用Client IDClient Secret 从创建的应用程序获取临时凭据(请求令牌)。

打开Postman,创建新呼叫http://website.com/oauth1/request, 单击授权选项卡,从下拉列表中选择OAuth 1.0,输入客户机密钥、客户机机密,将签名方法设置为HMAC-SHA1, 启用将参数添加到标头,encode oauth signature, 然后单击Update Request

Postman OAuth1 Request

Postman会自动为您生成签名、nonce和时间戳,并将它们添加到标题中(您可以在标题选项卡下查看)。

单击“发送”,您应该会得到一个响应,其中包括oauth_tokenoauth_token_secret:Postman OAuth1 Request Response

下一步将使用这些值授权WordPress用户帐户下的应用程序。

第二步(授权应用程序)

授权步骤只需完成一次,此步骤面向用户,每个人都熟悉。此步骤是必需的,因为您使用的是OAuth1,并且应用程序需要与WordPress用户帐户相关联。想想当一个网站允许你登录Facebook时。。。他们会将您引导到Facebook,在那里您可以登录并单击“授权”。。。这需要通过WordPress网站来完成。

我建议您在这一步中使用Web浏览器,因为您可以轻松地在URL中设置变量,这将提供“授权”页面来授权应用程序。

打开web浏览器并键入网站的URL,如下所示:http://website.com/oauth1/authorize

现在添加到此URL,oauth_consumer_key (客户ID),oauth_tokenoauth_token_secret (来自上一步)。在我的示例中,这是完整的URL:

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

OAuth1 Authorize Application

单击“授权”后,您将看到另一个带有验证令牌的屏幕。在我的示例中,这是返回的验证令牌E0JnxjjYxc32fMr2AF0uWsZm

第三步(获取访问令牌)

现在我们已经对应用程序进行了授权,我们需要进行最后一次调用,以获取将用于进行所有API调用的授权令牌。就像第一步一样,我将使用Postman(因为签名必须是HMAC-SHA1),这使完成这些步骤变得容易了100倍。

再次打开Postman,并将URL更改为http://website.com/oauth1/access

确保添加令牌和令牌机密(第一步中的值),然后单击Params 显示URL下方的框。在左侧键入oauth_verifier 在右侧,输入第二步的代码Verification Token

Postman OAuth1 Access Step

确保单击“更新请求”,然后单击“发送”,您应该会收到回复oauth_tokenoauth_token_secret ... 这就是您进行API调用所需要的!丢弃步骤1中的原始内容,将这些内容保存在代码中或其他安全的地方。

Postman OAuth1 Access Response

然后,可以对站点进行API调用,使用返回的令牌和令牌密钥设置标头。

您可以通过授权标头、GET参数或POST(如果编码为application/x-www-form-urlencoded)以多种方式传递此消息。请记住,您必须传递签名、时间戳和nonce。我不知道这个回复需要多长时间,所以明天我将用代码更新这个示例。

我强烈建议安装Rest API日志,以便您可以查看API调用的日志,并查看发送和返回的内容等。这将极大地帮助调试。

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

SO网友:sMyles

将此添加为另一个答案,以帮助您了解如何执行此操作。基本上正如我在评论中提到的,如果要使用OAuth1,必须将其与用户帐户相关联,这是无法避免的。

首先,您需要使用CURL以WordPress的用户名密码登录站点,存储cookie,以便在对OAuth的CURL调用中使用它(确保更新CURL调用以包含cookie):

https://stackoverflow.com/questions/724107/wordpress-autologin-using-curl-or-fsockopen-in-php

然后使用客户机ID和客户机机密的CURL调用OAuth,以获取临时OAuth令牌和机密(请求令牌)

要进行此调用(以及获取访问令牌的调用),需要正确设置CURL调用。有关代码和参考资料,请参阅此答案的结尾。

在获得临时oauth令牌和secret(请求令牌)后,对站点的此URL进行CURL POST调用:

http://website.com/oauth1/authorize

然后需要从返回的HTML中提取授权页面的所有值,然后将自己的帖子提交到表单操作URL。

https://stackoverflow.com/questions/35363815/how-to-get-a-value-input-from-html-returned-of-curl

具体而言,这些需要包含在您的帖子数据中,以完成“授权”发布到http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce -- 这是要提交的表单的nonce值,必须从HTML输入中提取该值并与您的帖子一起提交

    consumer -- 这是HTML中的隐藏输入(这是对帖子ID的引用,因此必须从HTML输入中提取它

    oauth_token -- 这是HTML中的一个隐藏输入(但您也应该已经有了)

    wp-submit -- 这需要设置为值authorize

    以下是为身份验证页面生成的HTML示例:

    <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>
    
    在您使用所有这些值/数据发表文章后,这是将返回的HTML,其中包含授权代码(因此您需要从<code> 块:

    <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>
    
    获得验证令牌后,您可以调用/oauth1/access 使用验证令牌、oauth令牌和oauth令牌密钥。验证令牌需要作为oauth_verifier

    这将返回您的新的永久访问令牌,瞧!

    下面的示例CURL代码是进行CURL调用的示例代码,最重要的部分是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;
    }
    
    // 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);
    
    该站点准确地说明了如何编码OAuth签名,以及如何使用CURL发送(我建议阅读整个页面):https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own-data/

    有关生成OAuth1签名的更多资源:https://stackoverflow.com/questions/24613277/oauth-signature-generation-using-hmac-sha1

    其他资源:http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/

SO网友:rudtek

我知道我来得有点晚,但你能用wp\\u remote\\u get和\\u post吗?

我正在使用wordpress安装拉取和发布内容:

这是wordpress codex的总体思路:

$response = wp_remote_post( $url, array(
    \'body\'    => $data,
    \'httpversion\' => \'1.0\',
    \'sslverify\' => false,
    \'headers\' => array(
        \'Authorization\' => \'Basic \' . base64_encode( $username . \':\' . $password ),
    ),
) );
下面是一个更具体的示例:

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

    }
    }
}
诀窍是对用户名和密码进行编码。现在,根据API用户名和pw,时间通常为空或是您的令牌。

例如,在我上面的具体示例中,标题是

\'headers\' => array(\'Authorization\' => \'Basic \' . base64_encode( \'MYTOKENID\' . \':\' . \'\' ))
我把pw留白了。这取决于您使用的API系统。

SO网友:juz

更新:据我所知,您需要进行多次卷曲以获取access\\u令牌,然后使用该令牌进行查询

临时凭据获取:客户端从服务器获取一组临时凭据

oauth1 server flow