EvaOAuth - 可能是目前最好的PHP OAuth庫

Allo發表於2015-05-02

來社群推薦一下自己的新作品。

EvaOAuth 是一個統一介面設計的PHP OAuth Client庫,相容OAuth1.0與OAuth2.0規範,可以通過10多行程式碼整合到任意專案中。

專案程式碼託管在 https://github.com/AlloVince/EvaOAuth ,歡迎Star及Fork貢獻程式碼。

為什麼選擇EvaOAuth

經過若干專案考驗, EvaOAuth1.0 根據實際需求進行了一次完全重構,主要的一些特性如下:

  • 標準介面,無論OAuth1.0或OAuth2.0,同一套程式碼實現不同工作流,並且獲取一致的資料格式,包括使用者資訊和Token。
  • 充分測試,所有關鍵程式碼進行單元測試,同時通過CI保證多版本PHP下的可用性。
  • 容易除錯,開啟Debug模式後,Log中會記錄OAuth流程中所有的URL、Request、Response,幫助定位問題。
  • 開箱即用,專案已經內建了主流的OAuth網址支援,如微博、QQ、Twitter、Facebook等。
  • 方便擴充套件,可以通過最少3行程式碼整合新的OAuth服務,工作流程提供事件機制。

快速開始

EvaOAuth可以通過Packagist下載,推薦通過Composer安裝。

編輯composer.json檔案為:

{
    "require": {
        "evaengine/eva-oauth": "~1.0"
    }
}

然後通過Composer進行安裝。

curl -sS https://getcomposer.org/installer | php
php composer.phar install

下面通過一個例項演示如何整合豆瓣登入功能。假設已經在豆瓣開發者建立好一個應用。準備一個request.php如下:

require_once './vendor/autoload.php'; //載入Composer自動生成的autoload
$service = new Eva\EvaOAuth\Service('Douban', [
    'key' => 'You Douban App ID',  //對應豆瓣應用的API Key
    'secret' => 'You Douban App Secret', //對應豆瓣應用的Secret
    'callback' => 'http://localhost/EvaOAuth/example/access.php' //回撥地址
]);
$service->requestAuthorize();

在瀏覽器中執行request.php,如果引數正確則會被重定向到豆瓣授權頁面,登入授權後會再次重定向回我們設定的callback。因此再準備好access.php檔案:

$token = $service->getAccessToken();

這樣就拿到了豆瓣的Access Token,接下來可以使用Token去訪問受保護的資源:

$httpClient = new Eva\EvaOAuth\AuthorizedHttpClient($token);
$response = $httpClient->get('https://api.douban.com/v2/user/~me');

這樣就完成了OAuth的登入功能。更多細節可以參考程式碼的示例以及Wiki頁面。

OAuth網站支援

EvaOAuth將一個OAuth網站稱為一個Provider。目前支援的Provider有:

  • OAuth2.0
    • 豆瓣(Douban)
    • Facebook
    • QQ (Tencent)
    • 微博 (Weibo)
  • OAuth1.0
    • Twitter

新增一個Provider僅需數行程式碼,下面演示如何整合Foursquare網站:

namespace YourNamespace;

class Foursquare extends \Eva\EvaOAuth\OAuth2\Providers\AbstractProvider
{
    protected $authorizeUrl = 'https://foursquare.com/oauth2/authorize';
    protected $accessTokenUrl = 'https://foursquare.com/oauth2/access_token';
}

然後將Provider註冊到EvaOAuth就可以使用了。

use Eva\EvaOAuth\Service;
Service::registerProvider('foursquare', 'YourNamespace\Foursquare');
$service = new Service('foursquare', [
    'key' => 'Foursquare App ID',
    'secret' => 'Foursquare App Secret',
    'callback' => 'http://somecallback/'
]);

資料儲存

在OAuth1.0的流程中,需要將Request Token儲存起來,然後在授權成功後使用Request Token換取Access Token。因此需要資料儲存功能。

EvaOAuth的資料儲存通過Doctrine\Cache實現。預設情況下EvaOAuth會將資料儲存為本地檔案,儲存路徑為EvaOAuth/tmp

可以在EvaOAuth初始化前任意更改儲存方式及儲存位置,例如將檔案儲存位置更改為/tmp

Service::setStorage(new Doctrine\Common\Cache\FilesystemCache('/tmp'));

或者使用Memcache儲存:

$storage = new \Doctrine\Common\Cache\MemcacheCache();
$storage->setMemcache(new \Memcache());
Service::setStorage($storage);

事件支援

EvaOAuth 定義了若干事件方面更容易的注入邏輯

  • BeforeGetRequestToken: 獲取Request Token前觸發。
  • BeforeAuthorize: 重定向到授權頁面前觸發。
  • BeforeGetAccessToken: 獲取Access Token前觸發。

比如我們希望在獲取Access Token前向HTTP請求中加一個自定義Header,可以通過以下方式實現:

$service->getEmitter()->on('beforeGetAccessToken', function(\Eva\EvaOAuth\Events\BeforeGetAccessToken $event) {
    $event->getRequest()->addHeader('foo', 'bar');
});

技術實現

EvaOAuth 基於強大的HTTP客戶端庫Guzzle,並通過OOP方式對OAuth規範進行了完整的描述。

為了避免對規範的詮釋上出現誤差,底層程式碼優先選擇規範描述中的角色與名詞,規範間差異則在上層程式碼中統一。

因此如果沒有同時支援兩套規範的需求,可以直接使用OAuth1.0、OAuth2.0分別對應的工作流。

詳細用例可以參考Wiki:

Debug與Log

開啟Debug模式將在Log中記錄所有的請求與響應。

$service->debug('/tmp/access.log');

請確保PHP對log檔案有寫入許可權。

API文件

首先通過pear install phpdoc/phpDocumentor安裝phpDocumentor,然後在專案根目錄下執行phpdoc,會在docs/下生成API文件。

問題反饋及貢獻程式碼

專案程式碼託管在 https://github.com/AlloVince/EvaOAuth ,歡迎Star及Fork貢獻程式碼。

有問題歡迎在EvaOAuth Issue提出。

相關文章