EvaOAuth 1.0:統一接口的OAuth登錄PHP類庫
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、推ter、非死book等。
- 方便擴展,可以通過最少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)
- 非死book
- QQ (Tencent)
- 微博 (Weibo)
- OAuth1.0
- 推ter
新增一個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提出。