系統API訪問受保護資源的機制(原創)

系統API訪問受保護資源的機制(原創)
餘超 [email protected]
如下是我參加新浪OpenAPI小組對於一個接口安全交互的流程,供大家參考,
系統API訪問機制包括接口註冊、安全校驗、訪問有效性檢驗的流程
如果接口沒有以上措施,此類接口均存在嚴重安全漏洞,一旦暴露在公網上,匿名用戶只要掃描到接口API鏈接,即可調用該接口獲取數據,
即使在內部也容易造成無意的數據泄露。爲了保證接口調用的安全,確保系統不會被惡意使用,
當第三方應用需要通過API訪問受保護的資源時,需要通過OAuth認證機制來獲得授權。
Open API 通過以下四個步驟來完成認證授權並訪問受保護的資源:
1. 獲取未授權的Request Token;
2. 請求平臺或用戶授權的Request Token;
3. 使用授權後的Request Token 換取Access Token;
4. 使用Access Token 訪問受保護的資源;
require_once 'examples-config.php';
require_once 'HTTP/OAuth/Consumer.php';

$consumer = new HTTP_OAuth_Consumer($config->consumer_key, $config->consumer_secret);
$consumer->accept($request);

$args = array();
if ($config->method == 'POST' && !empty($_GET['args'])) {
    $args = $config->args;
}

try {
    $consumer->getRequestToken($config->request_token_url, $config->callback_url,
        $args, $config->method);
    echo json_encode(
        array(
            'token'        => $consumer->getToken(),
            'token_secret' => $consumer->getTokenSecret()
        )
    );
} catch (HTTP_OAuth_Consumer_Exception_InvalidResponse $e) {
    echo get_class($e) . "<br>\n" .
        "<br>\n" . $e->getBody() . "<br>\n";
} catch (Exception $e) {
    echo get_class($e) . ': ' . $e->getMessage() . "\n";
}

$consumer = new HTTP_OAuth_Consumer('key', 'secret');
$consumer->getRequestToken('http://example.com/oauth/request_token', $callback);

// Store tokens
$_SESSION['token']        = $consumer->getToken();
$_SESSION['token_secret'] = $consumer->getTokenSecret();

$url = $consumer->getAuthorizeUrl('http://example.com/oauth/authorize');
http_redirect($url); // function from pecl_http

// When they come back via the $callback url
$consumer = new HTTP_OAuth_Consumer('key', 'secret', $_SESSION['token'],
    $_SESSION['token_secret']);
$consumer->getAccessToken('http://example.com/oauth/access_token');

// Store tokens
$_SESSION['token']        = $consumer->getToken();
$_SESSION['token_secret'] = $consumer->getTokenSecret();

// $response is an instance of HTTP_OAuth_Consumer_Response
$response = $consumer->sendRequest('http://example.com/oauth/protected_resource');

另外,通過密碼保護管理接口的安全性,設置管理會話超時,調用整個過程是否有加密?等等

參考如下:

Google的OAuth認證系統:
http://code.google.com/intl/zh-CN/apis/accounts/docs/OAuth_ref.html
認證代碼接口:
http://oauth.net/code/  參考PHP部分
PEAR 包 HTTP_OAuth:
http://pear.php.net/package/HTTP_OAuth_Provider
一個網站使用的實例:

https://atutor.ca/acontent/demo/documentation/oauth_server_api.php




爲了方便日後的維護,此認證流程相對比較麻煩些,所以在此整理一下
參考: http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html

大體介紹:
總流程分爲五步,分別是:

  1. 登錄Yahoo申請應用,得到consumer key 與 consumer secret
  2. 利用consumer key 與 consumer secret換取oauth_ token,即獲取請求令牌
  3. 引導用戶在Yahoo進行授權,並返回授權的認證簽名參數oauth_verifier,同時之前的oauth_ token也會一併返回
  4. 利用返回的oauth_verifier, oauth_token加上第一步的consumer key 與 consumer secret,加上第二步返回的oauth_token_secret,組合起來向Yahoo換取一個訪問令牌oauth_token(此時已經是可以訪問用戶數據的訪問令牌,跟之前的請求令牌不一樣)
  5. 當訪問令牌失效時,可以提交第四步返回的數據,交換一個新的有效令牌.


具體細節:

  1.   進入http://developer.yahoo.com/ 申請應用,注意App Domain一定要寫上自己的域名,不然之後的認證是無法通過的
  2.   在此做了一個引導腳本,此腳本主要通過curl獲取一個請求令牌,這裏請求地址上務必帶上oauth_callback 參數,這樣Yahoo返回的參數中就會有一個xoauth_request_auth_url 參數,此參數會引導用戶去Yahoo授權,這樣可以簡化我們去構造它的麻煩,此外,爲了在主腳本中能用到參數oauth_token_secret,在此我將它寫入cookie中
  3.   當授權成功後,Yahoo會引導用戶進入第2步中oauth_callback參數傳遞過來的地址,並帶有兩個參數oauth_verifier, oauth_token,接受這兩個參數,構造兌換訪問令牌的請求地址,在此注意的是oauth_signature 這裏根據Yahoo的要求,需要consumer secret與oauth_token_secret,並按consumer secret%26oauth_token_secret的要求賦值,這裏我們用的oauth_signature_method方法是PLAINTEXT,不然這oauth_signature的構造方法得遵從Oauth1.0的定義哦
  4.   兌換訪問令牌成功後會返回訪問令牌oauth_token,用戶唯一標識符xoauth_yahoo_guid,還有一個用於刷新過期訪問令牌的oauth_session_handle,當然訪問令牌的過期時間,這裏也一併返回了,讓咱們有個過期的心裏準備
  5.   到這裏了,也就沒啥好說的,我很少用到這個功能,要如果真的用的話,也跟第4步一樣的請求方式去跟Yahoo打個招呼,他就會返回給你,你想要的了認證做完了,到此處還好,基本一切正常,只是Yahoo的幫助文檔內容太少,沒有一些代碼例子,沒有一定的基礎還真的不容易懂啊

最讓人蛋疼的就是Yahoo的API了,幫助文檔上更一筆帶過,這叫Yahoo的Oauth1.0怎麼能被人廣泛使用呢?!
這裏,我也是找了一些資料取了一些自己要用的函數,來實現了,因爲Yahoo對於API中oauth_signature的要求,非得是HMAC-SHA1,不能是PLAINTEXT,所以這樣問題就來了,Yahoo把問題交給了Oauth官網,想必很多開發者都在這裏停住了吧,老是返回signature_invalid,看這些字母看得鬱悶至極,也找不到幫助資料,怎麼辦?繼續找,終於找到一個半成品,裏面正好有關於signature的生成函數,my God看了一下,這裏面的生成真是規矩啊,先給它參數排個序,再來hash_hmac加密,就這樣,這層紙被捅破了.另外開發者還得了解一下如何用curl發送請求頭信息,因爲oauth1.0的請求數據都是放在請求頭中的(可能這樣更有效率,不過怎麼更高級版本2.0的怎麼就沒有這樣處理)

眼見爲實,點擊看demo

比Yahoo提供的SDK簡單明瞭,下載地址

小結一下:
做Yahoo的Oauth1.0認證的朋友,要承受一定的心裏壓力,要在罵Yahoo的時候,也要相信他,同時基本的技能要紮實
PS:要想用Oauth來得到Yahoo的用戶自身的郵箱的朋友,請你獲取到後,告訴我一聲


發佈了46 篇原創文章 · 獲贊 5 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章