Làm cách nào để sử dụng xác thực OAuth với API REST thông qua các lệnh CURL?


18

Tôi đang cố gắng sử dụng WordPress Rest Api với xác thực để nhận thêm dữ liệu từ API. Tôi đã cài đặt plugin Oauth, plugin rest-api và nhận thông tin API từ WP-CLI.

Tôi đã tìm ra cách truy cập dữ liệu mà không được phép. Những công việc này:

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

Nhưng tôi không thể tìm ra cách xác thực bằng thông tin đăng nhập. Đây là nỗ lực của tôi. Tôi không chắc liệu "chìa khóa" và "bí mật" có đúng không.

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

Đầu ra là

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

Làm thế nào tôi có thể làm điều này để làm việc? Cảm ơn bạn.


2
Mọi thứ không dễ dàng như vậy. Tôi đã cố gắng viết một câu trả lời nhưng nó khá dài. Bạn có thể bắt đầu bằng cách đọc các tài liệu, đặc biệt là Luồng ủy quyền . Bài viết này cũng có một hướng dẫn tuyệt vời .
cybmeta

Câu trả lời:


10

Hãy đi từng bước ở đây. Có vẻ như bạn đang cố sử dụng OAuth chỉ để xác thực, nhưng trước khi bạn có thể làm như vậy, bạn cần lấy Mã thông báo truy cập sẽ được sử dụng để xác thực khi bạn thực hiện các lệnh gọi API.

Vì đây là sử dụng OAuth phiên bản 1, để có được Mã thông báo truy cập, bạn phải làm như sau:

  1. Đầu tiên, thiết lập một ứng dụng, thực hiện cuộc gọi đến trang web để nhận Mã thông báo yêu cầu (thông tin xác thực tạm thời) bằng ID khách hàng và Bí mật cho ứng dụng
  2. Thứ hai, thực hiện cuộc gọi đến trang web để Cấp quyền cho ứng dụng bằng Mã yêu cầu từ bước đầu tiên (hướng tới người dùng, xem bên dưới).
  3. Thứ ba, sau khi ủy quyền đã được hoàn thành, sau đó bạn thực hiện cuộc gọi đến trang web để nhận Mã thông báo truy cập (bây giờ ứng dụng đó đã được cấp phép)

Tôi khuyên bạn nên sử dụng Postman cho một vài bước đầu tiên, vì chúng chỉ cần được hoàn thành một lần. Postman cũng sẽ xử lý tạo ra timestamp, nonceoauth signature, vì vậy nếu bạn không sử dụng một thư viện OAuth, sau đó bạn hoàn toàn nên sử dụng Postman. Khi bạn có Mã thông báo truy cập, bạn có thể thực hiện các cuộc gọi qua CURL mà không cần bất kỳ thư viện nào.

https://www.getpostman.com/

Bước đầu tiên (thiết lập ứng dụng)

Cài đặt plugin WP OAuth 1, kích hoạt, sau đó chọn mục menu goto trong Người dùng> Ứng dụng . Thêm ứng dụng mới, điền tên và mô tả. Đối với cuộc gọi lại, URL để chuyển hướng người dùng đến (sau khi ủy quyền) hoặc oopcho luồng ngoài băng sẽ chuyển hướng đến một trang nội bộ hiển thị mã thông báo xác minh (thay vì chuyển hướng).

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

Để tiến hành bước thứ hai, một cuộc gọi cần được thực hiện đến trang web của bạn, sử dụng ID khách hàngBí mật khách hàng từ ứng dụng đã tạo, để có được thông tin xác thực tạm thời (Mã thông báo yêu cầu).

Mở Postman, tạo một cuộc gọi mới http://website.com/oauth1/request, nhấp vào tab Ủy quyền, chọn OAuth 1.0 từ danh sách thả xuống, nhập Khóa khách, Bí mật khách hàng, đặt phương thức chữ ký thành HMAC-SHA1, bật thêm thông số vào tiêu đề, mã hóa chữ ký oauth , sau đó bấm Cập nhật yêu cầu

Người gửi yêu cầu OAuth1

Người đưa thư sẽ tự động tạo chữ ký, nonce và dấu thời gian cho bạn và thêm chúng vào tiêu đề (bạn có thể xem trong tab Tiêu đề).

Nhấp vào Gửi và bạn sẽ nhận được phản hồi bao gồm oauth_tokenoauth_token_secret: Người đưa thư OAuth1 Yêu cầu trả lời

Các giá trị này sẽ được sử dụng trong bước tiếp theo để ủy quyền cho ứng dụng trong tài khoản người dùng WordPress của bạn.

Bước thứ hai (ủy quyền ứng dụng)

Bước ủy quyền chỉ cần được hoàn thành một lần, bước này là hướng tới người dùng và là bước mà mọi người đều quen thuộc. Bước này là bắt buộc vì bạn đang sử dụng OAuth1 và ứng dụng cần được liên kết với tài khoản người dùng WordPress. Hãy nghĩ đến khi một trang web cho phép bạn đăng nhập bằng Facebook ... họ sẽ đưa bạn đến Facebook nơi bạn đăng nhập và nhấp vào "Ủy quyền" ... việc này cần được thực hiện, chỉ cần thông qua trang web WordPress của bạn.

Tôi khuyên bạn nên sử dụng Trình duyệt web của mình cho bước này, vì bạn có thể dễ dàng đặt các biến trong URL và điều này cung cấp trang "Ủy quyền" để ủy quyền cho ứng dụng.

Mở trình duyệt web của bạn và nhập URL vào trang web của bạn, như thế này: http://website.com/oauth1/authorize

Bây giờ hãy thêm vào URL này, oauth_consumer_key(ID khách hàng) oauth_tokenoauth_token_secret(từ bước trước). Trong ví dụ của tôi đây là URL đầy đủ:

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

Ứng dụng ủy quyền OAuth1

Khi bạn nhấp vào Ủy quyền, bạn sẽ nhận được một màn hình khác với mã thông báo xác minh. Trong ví dụ của tôi, đây là mã thông báo xác minh được trả vềE0JnxjjYxc32fMr2AF0uWsZm

Bước thứ ba (nhận mã thông báo truy cập)

Bây giờ chúng tôi đã ủy quyền cho ứng dụng, chúng tôi cần thực hiện một cuộc gọi cuối cùng để nhận Mã thông báo ủy quyền sẽ được sử dụng để thực hiện tất cả các cuộc gọi API của bạn. Giống như bước đầu tiên tôi sẽ sử dụng Postman (vì chữ ký bắt buộc phải là HMAC-SHA1), và việc hoàn thành các bước này dễ dàng hơn gấp 100 lần.

Mở lại Postman và thay đổi URL thành http://website.com/oauth1/access

Đảm bảo thêm Mã thông báo và Mã thông báo bí mật (các giá trị từ bước đầu tiên), sau đó nhấp vào Params để hiển thị các hộp bên dưới URL. Ở loại bên trái trong oauth_verifier và bên phải, nhập mã từ bước thứ hai, Mã xác minh

Bước truy cập OAuth1 của Postman

Đảm bảo nhấp vào Yêu cầu cập nhật, sau đó nhấp vào Gửi và bạn sẽ nhận được phản hồi lại oauth_tokenoauth_token_secret... đây là những gì bạn cần để thực hiện các cuộc gọi API của mình! Hủy những cái ban đầu từ bước 1, lưu những cái này trong mã của bạn hoặc nơi nào khác an toàn.

Người trả lời truy cập OAuth1

Sau đó, bạn có thể thực hiện cuộc gọi API đến trang web của mình, đặt tiêu đề bằng mã thông báo được trả lại và bí mật mã thông báo.

Bạn có thể vượt qua nhiều cách này, thông qua tiêu đề Ủy quyền, trong các tham số GET hoặc POST (nếu được mã hóa dưới dạng application / x-www-form-urlencoding). Hãy nhớ rằng bạn PHẢI vượt qua chữ ký, dấu thời gian và nonce. Tôi đã không nhận ra câu trả lời này sẽ mất bao lâu, vì vậy tôi sẽ cập nhật vào ngày mai với ví dụ về việc thực hiện điều đó với mã của bạn.

Tôi thực sự khuyên bạn nên cài đặt Nhật ký API còn lại để bạn có thể xem nhật ký các lệnh gọi API và xem những gì đã được gửi, trả lại, v.v. Điều này sẽ giúp gỡ lỗi rất nhiều.

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


Tôi biết, có nhiều hướng dẫn với Postman hoặc các công cụ tương tự nhưng tôi không thể tìm thấy bất kỳ hướng dẫn nào thực hiện toàn bộ quá trình với các chức năng CURL, ý tôi là mã PHP thuần túy. Đó là điều tôi muốn.
MinhTri

@ Dan9 TBH điều đó không thực sự có thể ... ít nhất là không với OAuth1, chủ yếu là vì bạn phải ỦY QUYỀN ứng dụng trong tài khoản người dùng. Tất cả các bước khác đều dễ thực hiện với CURL, vấn đề là sử dụng CURL để đăng nhập với tư cách là người dùng WordPress (có nghĩa là bạn cần lưu trữ thông tin đăng nhập trong tệp PHP của bạn KHÔNG phải là ý tưởng hay), và ủy quyền cho ứng dụng mà bạn cho phép có thể sửa đổi cơ sở mã OAuth1, nhưng thành thật mà nói nếu bạn muốn sử dụng CURL để thực hiện MỌI THỨ ... bạn đang nghĩ về điều này sai cách, và nên đưa ra một giải pháp hoặc phương pháp khác.
sMstyle

@ Dan9 với những gì bạn đang cố gắng thực hiện, bạn nên sử dụng máy chủ OAuth2 thay vì OAuth1, chủ yếu vì thực tế là OAuth2 có các tính năng mới bao gồm loại cấp quyền Thông tin khách hàng, tránh phải trải qua tất cả các bước này bshaffer.github.io / oauth2-server-php-docs /
Grant

@ Dan9 nếu bạn được thiết lập 100% khi nhận trợ giúp khi thực hiện việc này thông qua OAuth1, sử dụng CURL, tôi nghĩ có thể với một vài hack mã, nhưng như tôi đã đề cập, điều này có nghĩa là bạn phải lưu USERNAME và PASSWORD của người dùng vào tệp PHP. Nếu bạn ổn với điều đó, hãy cho tôi biết và viết ra một hướng dẫn để làm điều đó bằng cách sử dụng CURL, đừng muốn dành thời gian viết hướng dẫn nếu bạn sẽ tiếp tục với OAuth2 hoặc không cần điều này nữa
sMstyle

@ Dan9 tốt ... chỉ vậy thôi ... nếu bạn sẽ sử dụng OAuth1, bạn phải liên kết Tài khoản người dùng WordPress. Về cơ bản, hãy nghĩ về Mã thông báo truy cập như khóa API ... "Khóa API" phải được liên kết với tài khoản người dùng ... bây giờ bạn có sử dụng một số tài khoản tiêu chuẩn mà bạn thiết lập hay không .. nhưng bất kể khi sử dụng OAuth1 PHẢI được liên kết với tài khoản người dùng, do đó quá trình dài để có được mã thông báo truy cập.
sMstyle

2

Thêm điều này như một câu trả lời khác để giúp bạn tìm ra cách để làm điều này. Về cơ bản như được đề cập trong các nhận xét của tôi nếu bạn sẽ sử dụng OAuth1, bạn PHẢI liên kết nó với tài khoản người dùng, không có cách nào khác.

Trước tiên, bạn cần sử dụng CURL để đăng nhập vào trang web bằng mật khẩu tên người dùng cho WordPress, lưu trữ cookie để bạn có thể sử dụng nó trong cuộc gọi CURL của bạn đến OAuth (đảm bảo cập nhật cuộc gọi CURL của bạn để bao gồm cookie):

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

Sau đó thực hiện cuộc gọi đến OAuth bằng cách sử dụng CURL với ID khách hàng và Bí mật khách hàng, để có được mã thông báo tạm thời và bí mật (Mã thông báo yêu cầu)

Để thực hiện cuộc gọi này (và cuộc gọi để nhận mã thông báo truy cập), bạn cần thiết lập chính xác cuộc gọi CURL của mình. Xem cuối câu trả lời này cho mã và tài liệu tham khảo.

Sau khi bạn nhận được mã thông báo tạm thời và bí mật (Mã thông báo yêu cầu), hãy thực hiện cuộc gọi POSTL POST tới URL này của trang web của bạn:

http://website.com/oauth1/authorize

Sau đó, bạn sẽ cần phải kéo tất cả các giá trị từ HTML được trả về cho trang ủy quyền và sau đó gửi POST của riêng bạn tới URL hành động biểu mẫu.

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

Cụ thể những thứ này cần được đưa vào dữ liệu POST của bạn để hoàn thành việc POST "ủy quyền" http://domain.com/wp-login.php?action=oauth1_authorize

  • _wpnonce - Đây là giá trị nonce cho biểu mẫu được gửi, PHẢI này được lấy từ đầu vào HTML và được gửi bằng POST của bạn

    consumer - Đây là một đầu vào ẩn trong HTML (đây là tham chiếu đến ID bài đăng nên bạn phải lấy nó từ đầu vào HTML

    oauth_token - Đây là một đầu vào ẩn trong HTML (nhưng bạn cũng nên có cái này)

    wp-submit - Điều này cần phải được đặt thành giá trị authorize

Đây là ví dụ HTML được tạo cho trang xác thực:

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

Sau khi bạn tạo POST với tất cả các giá trị / dữ liệu đó, đây là HTML sẽ được trả về bằng mã ủy quyền (vì vậy bạn cần phải kéo giá trị từ bên trong <code>khối:

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

Khi bạn có mã thông báo xác minh, sau đó bạn có thể thực hiện cuộc gọi để /oauth1/accesssử dụng mã xác minh, mã thông báo oauth và bí mật mã thông báo oauth. Mã thông báo xác minh cần được đặt trong dữ liệu POST nhưoauth_verifier

Điều đó sẽ trả về Mã thông báo truy cập mới và vĩnh viễn của bạn và VOILA!

Ví dụ mã CURL

Dưới đây là mã ví dụ để thực hiện cuộc gọi CURL, phần quan trọng nhất là cách oauth_signaturetạo ra:

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

Trang web này cho biết chính xác cách mã hóa chữ ký OAuth và cách gửi bằng cách sử dụng CURL (tôi khuyên bạn nên đọc toàn bộ trang): https://hannah.wf/twitter-oauth-simple-curl-requests-for-your-own- dữ liệu/

Thêm tài nguyên về việc tạo chữ ký OAuth1: /programming/24613277/oauth-signature-generation-USE-hmac-sha1

Tài nguyên khác: http://collaboradev.com/2011/04/01/twitter-oauth-php-tutorial/


Làm cách nào tôi có thể lấy ID khách hàng và bí mật của Khách hàng và liên kết nó với người dùng hợp lệ? Hiện tại, chỉ quản trị viên mới có thể tạo một ứng dụng mới và nó chỉ xảy ra thông qua bảng điều khiển quản trị viên. Btw, tôi đã cố gắng tạo ra oauth_signaturenhư bạn đã nói nhưng, bằng cách nào đó, phản hồi luôn luôn json_oauth1_signature_mismatch.
MinhTri

@ Dan9 đúng vậy, quản trị viên phải tạo ứng dụng, nếu không đó sẽ là một vấn đề bảo mật rất lớn cho phép các ứng dụng được tạo bởi người dùng ẩn danh. Đây là một số trang web liên quan đến chữ ký wordpress.stackexchange.com/questions/185511/, github.com/WP-API/OAuth1/issues
432

0

Cập nhật: Từ những gì tôi đã đọc, bạn cần thực hiện nhiều lọn tóc để có được access_token, sau đó bạn sử dụng để thực hiện truy vấn

  • Thu thập thông tin xác thực tạm thời: Khách hàng nhận được một bộ thông tin xác thực tạm thời từ máy chủ.
  • Ủy quyền: Người dùng "ủy quyền" mã thông báo yêu cầu truy cập vào tài khoản của họ.
  • Trao đổi mã thông báo: Khách hàng trao đổi thông tin xác thực tạm thời ngắn hạn cho mã thông báo tồn tại lâu dài.

lưu lượng máy chủ oauth1


0

Tôi biết tôi đến đây hơi muộn, nhưng bạn có thể sử dụng wp_remote_get và _post không?

Tôi đang kéo và đăng nội dung với cài đặt wordpress của mình bằng cách sử dụng chúng:

Đây là ý tưởng chung từ codex wordpress:

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

Dưới đây là một ví dụ cụ thể hơn:

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

    }
    }
}

Thủ thuật là mã hóa tên người dùng và pw. Bây giờ thường thời gian tùy thuộc vào tên người dùng API và pw sẽ trống hoặc sẽ là mã thông báo của bạn.

vì vậy, ví dụ trong ví dụ cụ thể của tôi ở trên, các tiêu đề là

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

và tôi để trống pw. Điều đó tùy thuộc vào hệ thống API mà bạn đang sử dụng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.